qs_codec package¶
Subpackages¶
- qs_codec.enums package
- qs_codec.models package
- Submodules
- qs_codec.models.decode_options module
DecodeOptions
DecodeOptions.allow_dots
DecodeOptions.allow_empty_lists
DecodeOptions.charset
DecodeOptions.charset_sentinel
DecodeOptions.comma
DecodeOptions.decode()
DecodeOptions.decode_dot_in_keys
DecodeOptions.decode_key()
DecodeOptions.decode_value()
DecodeOptions.decoder()
DecodeOptions.delimiter
DecodeOptions.depth
DecodeOptions.duplicates
DecodeOptions.ignore_query_prefix
DecodeOptions.interpret_numeric_entities
DecodeOptions.legacy_decoder
DecodeOptions.list_limit
DecodeOptions.parameter_limit
DecodeOptions.parse_lists
DecodeOptions.raise_on_limit_exceeded
DecodeOptions.strict_depth
DecodeOptions.strict_null_handling
- qs_codec.models.encode_options module
EncodeOptions
EncodeOptions.add_query_prefix
EncodeOptions.allow_dots
EncodeOptions.allow_empty_lists
EncodeOptions.charset
EncodeOptions.charset_sentinel
EncodeOptions.comma_round_trip
EncodeOptions.delimiter
EncodeOptions.encode
EncodeOptions.encode_dot_in_keys
EncodeOptions.encode_values_only
EncodeOptions.encoder
EncodeOptions.filter
EncodeOptions.format
EncodeOptions.indices
EncodeOptions.list_format
EncodeOptions.serialize_date()
EncodeOptions.skip_nulls
EncodeOptions.sort
EncodeOptions.strict_null_handling
- qs_codec.models.undefined module
- qs_codec.models.weak_wrapper module
- Module contents
- qs_codec.utils package
Submodules¶
qs_codec.decode module¶
Query string decoder (a.k.a. parser) with feature parity to the Node.js qs package.
Highlights¶
Accepts either a raw query string or a pre-tokenized mapping (mirrors qs.parse).
Supports RFC 3986 / 1738 percent-decoding via DecodeOptions.decoder.
Handles bracket notation, indices, dotted keys (opt-in), and duplicate keys strategies.
Respects list parsing limits, depth limits, and charset sentinels (utf8=%E2%9C%93 / utf8=%26%2310003%3B).
Returns plain dict / list containers and never mutates the caller’s input.
This module intentionally keeps the control flow close to the original reference implementation so that behavior across ports stays predictable and easy to verify with shared test vectors.
- qs_codec.decode.decode(value: str | Mapping[str, Any] | None, options: DecodeOptions | None = None) Dict[str, Any] [source]¶
Decode a query string (or a pre-tokenized mapping) into a nested
Dict[str, Any]
.- Parameters:
value – Either a raw query string (
str
) or an already-parsed mapping (Mapping[str, Any]
). Passing a mapping is useful in tests or when a custom tokenizer is used upstream.options –
DecodeOptions
controlling delimiter, duplicates policy, list & depth limits, dot-notation, decoding charset, and more.
- Returns:
A freshly-allocated mapping containing nested dicts/lists/values.
- Return type:
Dict[str, Any]
- Raises:
ValueError – If
value
is neitherstr
norMapping
, or when limits are violated underraise_on_limit_exceeded=True
.
Notes
Empty/falsey
value
returns an empty dict.When the number of top-level tokens exceeds
list_limit
andparse_lists
is enabled, the parser temporarily disables list parsing for this invocation to avoid quadratic work. This mirrors the behavior of other ports and keeps large flat query strings efficient.
- qs_codec.decode.load(value: str | Mapping[str, Any] | None, options: DecodeOptions | None = None) Dict[str, Any] ¶
Decode a query string (or a pre-tokenized mapping) into a nested
Dict[str, Any]
.- Parameters:
value – Either a raw query string (
str
) or an already-parsed mapping (Mapping[str, Any]
). Passing a mapping is useful in tests or when a custom tokenizer is used upstream.options –
DecodeOptions
controlling delimiter, duplicates policy, list & depth limits, dot-notation, decoding charset, and more.
- Returns:
A freshly-allocated mapping containing nested dicts/lists/values.
- Return type:
Dict[str, Any]
- Raises:
ValueError – If
value
is neitherstr
norMapping
, or when limits are violated underraise_on_limit_exceeded=True
.
Notes
Empty/falsey
value
returns an empty dict.When the number of top-level tokens exceeds
list_limit
andparse_lists
is enabled, the parser temporarily disables list parsing for this invocation to avoid quadratic work. This mirrors the behavior of other ports and keeps large flat query strings efficient.
- qs_codec.decode.loads(value: str | None, options: DecodeOptions | None = None) Dict[str, Any] [source]¶
Alias for
decode
. Decodes a query string into aDict[str, Any]
.Use
decode
if you want to pass aDict[str, Any]
.
qs_codec.encode module¶
Query‑string encoder (stringifier).
This module converts Python mappings and sequences into a percent‑encoded query string with feature parity to the Node.js qs package where it makes sense for Python. It supports:
Stable, deterministic key ordering with an optional custom comparator.
Multiple list encodings (indices, brackets, repeat key, comma) including the “comma round‑trip” behavior to preserve single‑element lists.
Custom per‑scalar encoder and datetime serializer hooks.
RFC 3986 vs RFC 1738 formatting and optional charset sentinels.
Dots vs brackets in key paths (allow_dots, encode_dot_in_keys).
Strict/null handling, empty‑list emission, and cycle detection.
Nothing in this module mutates caller objects: inputs are shallow‑normalized and deep‑copied only where safe/necessary to honor options.
- qs_codec.encode.dumps(value: ~typing.Any, options: ~qs_codec.models.encode_options.EncodeOptions = EncodeOptions(allow_dots=False, add_query_prefix=False, allow_empty_lists=False, indices=None, list_format=<ListFormat.INDICES: list_format_name='INDICES', generator=<function ListFormatGenerator.indices>>, charset=<Charset.UTF8: encoding='utf-8'>, charset_sentinel=False, delimiter='&', encode=True, encode_dot_in_keys=False, encode_values_only=False, format=<Format.RFC3986: format_name='RFC3986', formatter=<function Formatter.rfc3986>>, filter=None, skip_nulls=False, serialize_date=<function EncodeUtils.serialize_date>, encoder=<function EncodeOptions.encoder.<locals>.<lambda>>, strict_null_handling=False, comma_round_trip=None, sort=None)) str ¶
Stringify a Python value into a query string.
- Parameters:
value – The object to encode. Accepted shapes: * Mapping -> encoded as-is. * Sequence (list/tuple) -> treated as an object with string indices. * Other/None -> treated as empty input.
options – Encoding behavior (parity with the Node.js qs API).
- Returns:
The encoded query string (possibly prefixed with “?” if requested), or an empty string when there is nothing to encode.
Notes
Caller input is not mutated. When a mapping is provided it is deep-copied; sequences are projected to a temporary mapping.
If a callable filter is provided, it can transform the root object.
If an iterable filter is provided, it selects which root keys to emit.
- qs_codec.encode.encode(value: ~typing.Any, options: ~qs_codec.models.encode_options.EncodeOptions = EncodeOptions(allow_dots=False, add_query_prefix=False, allow_empty_lists=False, indices=None, list_format=<ListFormat.INDICES: list_format_name='INDICES', generator=<function ListFormatGenerator.indices>>, charset=<Charset.UTF8: encoding='utf-8'>, charset_sentinel=False, delimiter='&', encode=True, encode_dot_in_keys=False, encode_values_only=False, format=<Format.RFC3986: format_name='RFC3986', formatter=<function Formatter.rfc3986>>, filter=None, skip_nulls=False, serialize_date=<function EncodeUtils.serialize_date>, encoder=<function EncodeOptions.encoder.<locals>.<lambda>>, strict_null_handling=False, comma_round_trip=None, sort=None)) str [source]¶
Stringify a Python value into a query string.
- Parameters:
value – The object to encode. Accepted shapes: * Mapping -> encoded as-is. * Sequence (list/tuple) -> treated as an object with string indices. * Other/None -> treated as empty input.
options – Encoding behavior (parity with the Node.js qs API).
- Returns:
The encoded query string (possibly prefixed with “?” if requested), or an empty string when there is nothing to encode.
Notes
Caller input is not mutated. When a mapping is provided it is deep-copied; sequences are projected to a temporary mapping.
If a callable filter is provided, it can transform the root object.
If an iterable filter is provided, it selects which root keys to emit.
Module contents¶
Query string encoding/decoding for Python.
This package is a Python port of the popular qs library for JavaScript/Node.js. It strives to match qs semantics and edge cases — including list/array formats, duplicate key handling, RFC 3986 vs RFC 1738 formatting, character set sentinels, and other interoperability details.
The package root re-exports the most commonly used functions and enums so you can:
>>> from qs_codec import encode, decode, ListFormat, EncodeOptions
>>> encode({"a": [1, 2, 3]}, options=EncodeOptions(list_format=ListFormat.brackets))
'a[]=1&a[]=2&a[]=3'
- class qs_codec.Charset(*values)[source]
Bases:
_CharsetDataMixin
,Enum
Supported character sets for query-string processing.
Each enum member’s value is the codec string understood by Python’s encoding APIs. Prefer accessing
encoding
instead of hard-coding literals.- LATIN1 = _CharsetDataMixin(encoding='iso-8859-1')
ISO-8859-1 (Latin-1) character encoding.
- UTF8 = _CharsetDataMixin(encoding='utf-8')
UTF-8 character encoding.
- class qs_codec.DecodeKind(*values)[source]
Bases:
str
,Enum
Decoding context for query string tokens.
- KEY
Decode a key (or key segment). Note that the default scalar decoder (
qs_codec.utils.decode_utils.decode
) ignores kind and fully decodes percent-encoded dots (%2E
/%2e
). Dot-splitting behavior is applied later by higher-level parser options.
- VALUE
Decode a value. Implementations typically perform full percent decoding.
- KEY = 'key'
- VALUE = 'value'
- class qs_codec.DecodeOptions(allow_dots: bool | None = None, decode_dot_in_keys: bool | None = None, allow_empty_lists: bool = False, list_limit: int = 20, charset: ~qs_codec.enums.charset.Charset = Charset.UTF8, charset_sentinel: bool = False, comma: bool = False, delimiter: str | ~typing.Pattern[str] = '&', depth: int = 5, parameter_limit: int | float = 1000, duplicates: ~qs_codec.enums.duplicates.Duplicates = Duplicates.COMBINE, ignore_query_prefix: bool = False, interpret_numeric_entities: bool = False, parse_lists: bool = True, strict_depth: bool = False, strict_null_handling: bool = False, raise_on_limit_exceeded: bool = False, decoder: ~typing.Callable[[...], str | None] | None = <bound method DecodeUtils.decode of <class 'qs_codec.utils.decode_utils.DecodeUtils'>>, legacy_decoder: ~typing.Callable[[...], str | None] | None = None)[source]
Bases:
object
Options that configure the output of
decode
.- allow_dots: bool | None = None
Set to
True
to decode dotdict
notation in the encoded input. WhenNone
(default), it inherits the value ofdecode_dot_in_keys
.
- allow_empty_lists: bool = False
Set to
True
to allow emptylist
values insidedict
s in the encoded input.
- charset: Charset = _CharsetDataMixin(encoding='utf-8')
The character encoding to use when decoding the input.
- charset_sentinel: bool = False
Some services add an initial
utf8=✓
value to forms so that old InternetExplorer versions are more likely to submit the form asutf-8
. Additionally, the server can check the value against wrong encodings of the checkmark character and detect that a query string orapplication/x-www-form-urlencoded
body was not sent asutf-8
, e.g. if the form had anaccept-charset
parameter or the containing page had a different character set.qs_codec
supports this mechanism via thecharset_sentinel
option. If specified, theutf-8
parameter will be omitted from the returneddict
. It will be used to switch toLATIN1
orUTF8
mode depending on how the checkmark is encoded.Important: When you specify both the
charset
option and thecharset_sentinel
option, thecharset
will be overridden when the request contains autf-8
parameter from which the actual charset can be deduced. In that sense thecharset
will behave as the default charset rather than the authoritative charset.
- comma: bool = False
Set to
True
to parse the input as a comma-separated value. Note: nesteddict
s, such as'a={b:1},{c:d}'
are not supported.
- decode(value: str | None, charset: Charset | None = None, *, kind: DecodeKind = DecodeKind.VALUE) Any | None [source]
Unified scalar decode with key/value context.
Uses the configured
decoder
(orlegacy_decoder
) when provided; otherwise falls back toDecodeUtils.decode()
. The default library behavior decodes keys identically to values; whether a.
participates in key splitting is decided later by the parser.
- decode_dot_in_keys: bool | None = None
Set to
True
to decode percent‑encoded dots in keys (e.g.,%2E
→.
). Note: it impliesallow_dots
, sodecode
will error if you setdecode_dot_in_keys
toTrue
, andallow_dots
toFalse
. WhenNone
(default), it defaults toFalse
.Inside bracket segments, percent-decoding naturally yields
.
from%2E/%2e
. This option controls whether top‑level encoded dots are treated as additional split points; it does not affect the literal.
produced by percent-decoding inside bracket segments.
- decode_key(value: str | None, charset: Charset | None = None) str | None [source]
Decode a key (or key segment). Always returns a string or
None
.Note: custom decoders returning non-strings for keys are coerced via
str()
.
- decode_value(value: str | None, charset: Charset | None = None) Any | None [source]
Decode a value token. Returns any scalar or
None
.
- classmethod decoder(string: str | None, charset: Charset | None = Charset.UTF8, kind: DecodeKind = DecodeKind.VALUE) str | None
Decode a URL‑encoded scalar.
Notes
The kind parameter is accepted for API compatibility but is currently ignored; keys and values are decoded identically. It may be removed in a future major release.
Behavior: - Replace
+
with a literal space before decoding. - Ifcharset
isLATIN1
, decode only%XX
byte sequences (no%uXXXX
).%uXXXX
sequences are left as‑is to mimic older browser/JS behavior. - Otherwise (UTF‑8), defer tourllib.parse.unquote()
. - Keys and values are decoded identically; whether a literal.
acts as a key separator is decided later by the key‑splitting logic.- Returns:
None
when the input isNone
.- Return type:
Optional[str]
- delimiter: str | Pattern[str] = '&'
The delimiter to use when splitting key-value pairs in the encoded input. Can be a
str
or aPattern
.
- depth: int = 5
By default, when nesting
dict
sqs_codec
will only decode up to 5 children deep. This depth can be overridden by setting thedepth
. The depth limit helps mitigate abuse whenqs_codec
is used to parse user input, and it is recommended to keep it a reasonably small number.
- duplicates: Duplicates = 1
Strategy for handling duplicate keys in the input.
COMBINE
(default): merge values into a list (e.g.,a=1&a=2
→{"a": [1, 2]}
).FIRST
: keep the first value and ignore subsequent ones ({"a": 1}
).LAST
: keep only the last value seen ({"a": 2}
).
- ignore_query_prefix: bool = False
Set to
True
to ignore the leading question mark query prefix in the encoded input.
- interpret_numeric_entities: bool = False
Set to
True
to interpret HTML numeric entities (&#...;
) in the encoded input.
- legacy_decoder: Callable[[...], str | None] | None = None
Back‑compat adapter for legacy decoders of the form
decoder(value, charset)
. Preferdecoder
which may optionally accept akind
argument. When both are supplied,decoder
takes precedence (mirroring Kotlin/C#/Swift/Dart behavior).
- list_limit: int = 20
20
).During decoding, keys like
a[0]
,a[1]
, … are treated as list indices. If an index exceeds this limit, the container is treated as adict
instead, with the numeric index kept as a string key (e.g.,{"999": "x"}
) to prevent creation of massive sparse lists (e.g.,a[999999999]
).This limit also applies to comma–split lists when
comma=True
. Set a larger value if you explicitly need more items, or set a smaller one to harden against abuse.- Type:
Maximum number of indexed items allowed in a single list (default
- parameter_limit: int | float = 1000
For similar reasons, by default
qs_codec
will only parse up to 1000 parameters. This can be overridden by passing aparameter_limit
option.
- parse_lists: bool = True
To disable
list
parsing entirely, setparse_lists
toFalse
.
- raise_on_limit_exceeded: bool = False
Raise instead of degrading gracefully when limits are exceeded.
When
True
, the decoder raises: - aDecodeError
for parameter and list limit violations; and - anIndexError
when nesting deeper thandepth
andstrict_depth=True
.When
False
(default), the decoder degrades gracefully: it slices the parameter list atparameter_limit
, stops adding items beyondlist_limit
, and—ifstrict_depth=True
—stops descending oncedepth
is reached without raising.
- strict_depth: bool = False
Enforce the
depth
limit when decoding nested structures.When
True
, the decoder will not descend beyonddepth
levels. Combined withraise_on_limit_exceeded
:if
raise_on_limit_exceeded=True
, exceeding the depth raises anIndexError
;if
False
, the decoder stops descending and treats deeper content as a terminal value, preserving the last valid container without raising.
- strict_null_handling: bool = False
Set to
True
to decode values without=
toNone
.
- class qs_codec.Duplicates(*values)[source]
Bases:
Enum
Defines how to resolve duplicate keys produced during parsing.
This is consulted by the decoder when more than one value is encountered for the same key. It does not affect encoding.
Members¶
- COMBINE
Combine duplicate keys into a single list of values (preserves order).
- FIRST
Keep only the first occurrence and discard subsequent ones.
- LAST
Keep only the last occurrence, overwriting prior ones.
- COMBINE = 1
Combine duplicate keys into a single list of values (preserves order).
- FIRST = 2
Keep only the first value encountered for the key.
- LAST = 3
Keep only the last value encountered for the key.
- class qs_codec.EncodeOptions(allow_dots: bool = None, add_query_prefix: bool = False, allow_empty_lists: bool = False, indices: bool | None = None, list_format: ~qs_codec.enums.list_format.ListFormat = ListFormat.INDICES, charset: ~qs_codec.enums.charset.Charset = Charset.UTF8, charset_sentinel: bool = False, delimiter: str = '&', encode: bool = True, encode_dot_in_keys: bool = None, encode_values_only: bool = False, format: ~qs_codec.enums.format.Format = Format.RFC3986, filter: ~typing.Callable | ~typing.List[str | int] | None = None, skip_nulls: bool = False, serialize_date: ~typing.Callable[[~datetime.datetime], str | None] = <function EncodeUtils.serialize_date>, encoder: ~typing.Callable[[~typing.Any, ~qs_codec.enums.charset.Charset | None, ~qs_codec.enums.format.Format | None], str] = <property object>, strict_null_handling: bool = False, comma_round_trip: bool | None = None, sort: ~typing.Callable[[~typing.Any, ~typing.Any], int] | None = None)[source]
Bases:
object
Options that configure the output of encode.
Each field corresponds to a knob in the query-string encoder. Defaults aim to be unsurprising and compatible with other Techouse qs ports. See per-field docs below for details and caveats.
- add_query_prefix: bool = False
When True, prefix the output with a ? (useful when appending to a base URL).
- allow_dots: bool = None
When True, interpret dotted keys as object paths during encoding (e.g. a.b=1). If None, mirrors encode_dot_in_keys (see __post_init__).
- allow_empty_lists: bool = False
When True, include empty lists in the output (e.g. a[]= instead of omitting).
- charset: Charset = _CharsetDataMixin(encoding='utf-8')
Character encoding used by the encoder (defaults to UTF‑8).
- charset_sentinel: bool = False
When True, include a sentinel parameter announcing the charset (e.g. utf8=✓).
- comma_round_trip: bool | None = None
Only used with ListFormat.COMMA. When True, single‑item lists append [] so they round‑trip back to a list on decode.
- delimiter: str = '&'
Pair delimiter between tokens (typically &; ; and others are allowed).
- encode: bool = True
Master switch. When False, values/keys are not percent‑encoded (joined as-is).
- encode_dot_in_keys: bool = None
When True, encode dots in keys literally. With encode_values_only=True, only key dots are encoded while values remain untouched.
- encode_values_only: bool = False
When True, the encoder is applied to values only; keys are left unencoded.
- property encoder: Callable[[Any, Charset | None, Format | None], str]
Return a view of the encoder bound to the current charset and format.
The returned callable has signature (value) -> str and internally calls the underlying _encoder(value, self.charset, self.format).
- filter: Callable | List[str | int] | None = None
Restrict which keys get included. - If a callable is provided, it is invoked for each key and should return the replacement value (or None to drop when skip_nulls applies). - If a list is provided, only those keys/indices are retained.
- format: Format = _FormatDataMixin(format_name='RFC3986', formatter=<function Formatter.rfc3986>)
Space handling and percent‑encoding style. RFC3986 encodes spaces as %20, while RFC1738 uses +.
- indices: bool | None = None
prefer list_format. If set, maps to ListFormat.INDICES when True or ListFormat.REPEAT when False.
- Type:
Deprecated
- list_format: ListFormat = _ListFormatDataMixin(list_format_name='INDICES', generator=<function ListFormatGenerator.indices>)
Controls how lists are encoded (indices/brackets/repeat/comma). See ListFormat.
- serialize_date() str
Serialize a datetime to ISO‑8601 using datetime.isoformat().
- skip_nulls: bool = False
When True, omit keys whose value is None entirely (no trailing =).
- sort: Callable[[Any, Any], int] | None = None
Optional comparator for deterministic key ordering. Must return -1, 0, or +1.
- strict_null_handling: bool = False
None → a (no =), empty string → a=.
- Type:
When True, distinguish empty strings from None
- class qs_codec.Format(*values)[source]
Bases:
_FormatDataMixin
,Enum
Supported URI component formatting profiles.
Each enum value packs a
(format_name, formatter)
tuple. After raw percent-encoding is performed by the encoder, the selected profile’sformatter
is called to adjust the final textual representation (e.g., mapping"%20"
to"+"
for RFC 1738).- RFC1738 = _FormatDataMixin(format_name='RFC1738', formatter=<function Formatter.rfc1738>)
- RFC3986 = _FormatDataMixin(format_name='RFC3986', formatter=<function Formatter.rfc3986>)
- class qs_codec.ListFormat(*values)[source]
Bases:
_ListFormatDataMixin
,Enum
Available list formatting options for the encoder.
Each member pairs a stable name with a generator function from
ListFormatGenerator
:BRACKETS
:foo[]
for each element.INDICES
:foo[0]
,foo[1]
, …REPEAT
: repeat the key per value (foo=1&foo=2
).COMMA
: single key with comma‑joined values (foo=1,2
).
These options control only how keys are produced; value encoding and delimiter handling are governed by other options.
- BRACKETS = _ListFormatDataMixin(list_format_name='BRACKETS', generator=<function ListFormatGenerator.brackets>)
Use brackets to represent list items, for example
foo[]=123&foo[]=456&foo[]=789
.
- COMMA = _ListFormatDataMixin(list_format_name='COMMA', generator=<function ListFormatGenerator.comma>)
Use commas to represent list items, for example
foo=123,456,789
.
- INDICES = _ListFormatDataMixin(list_format_name='INDICES', generator=<function ListFormatGenerator.indices>)
Use indices to represent list items, for example
foo[0]=123&foo[1]=456&foo[2]=789
.
- REPEAT = _ListFormatDataMixin(list_format_name='REPEAT', generator=<function ListFormatGenerator.repeat>)
Use a repeat key to represent list items, for example
foo=123&foo=456&foo=789
.
- class qs_codec.Sentinel(*values)[source]
Bases:
_SentinelDataMixin
,Enum
All supported
utf8
sentinels.- Each enum member provides:
raw
: the source token a browser starts with, andencoded
: the final, percent-encodedutf8=…
fragment.
- CHARSET = _SentinelDataMixin(raw='✓', encoded='utf8=%E2%9C%93')
UTF‑8 sentinel indicating the request is UTF‑8 encoded.
This is the percent‑encoded UTF‑8 sequence for ✓, yielding the fragment
utf8=%E2%9C%93
.
- ISO = _SentinelDataMixin(raw='✓', encoded='utf8=%26%2310003%3B')
HTML‑entity sentinel used by non‑UTF‑8 submissions.
When a check mark (✓) appears but the page/form encoding is
iso-8859-1
(or another charset that lacks ✓), browsers first HTML‑entity‑escape it as"✓"
and then URL‑encode it, producingutf8=%26%2310003%3B
.
- class qs_codec.Undefined[source]
Bases:
object
Singleton sentinel object representing an “undefined” value.
Notes
This is not the same as None. Use None to represent a null value and Undefined() to represent “no value / omit”.
All calls to
Undefined()
return the same instance. Prefer identity checks (is
) over equality checks.
Examples
>>> from qs_codec.models.undefined import Undefined >>> a = Undefined() >>> b = Undefined() >>> a is b True >>> # Use it to indicate a key should be omitted when encoding: >>> maybe_value = Undefined() >>> if maybe_value is Undefined(): ... pass # skip emitting the key
- qs_codec.decode(value: str | Mapping[str, Any] | None, options: DecodeOptions | None = None) Dict[str, Any] [source]
Decode a query string (or a pre-tokenized mapping) into a nested
Dict[str, Any]
.- Parameters:
value – Either a raw query string (
str
) or an already-parsed mapping (Mapping[str, Any]
). Passing a mapping is useful in tests or when a custom tokenizer is used upstream.options –
DecodeOptions
controlling delimiter, duplicates policy, list & depth limits, dot-notation, decoding charset, and more.
- Returns:
A freshly-allocated mapping containing nested dicts/lists/values.
- Return type:
Dict[str, Any]
- Raises:
ValueError – If
value
is neitherstr
norMapping
, or when limits are violated underraise_on_limit_exceeded=True
.
Notes
Empty/falsey
value
returns an empty dict.When the number of top-level tokens exceeds
list_limit
andparse_lists
is enabled, the parser temporarily disables list parsing for this invocation to avoid quadratic work. This mirrors the behavior of other ports and keeps large flat query strings efficient.
- qs_codec.dumps(value: ~typing.Any, options: ~qs_codec.models.encode_options.EncodeOptions = EncodeOptions(allow_dots=False, add_query_prefix=False, allow_empty_lists=False, indices=None, list_format=<ListFormat.INDICES: list_format_name='INDICES', generator=<function ListFormatGenerator.indices>>, charset=<Charset.UTF8: encoding='utf-8'>, charset_sentinel=False, delimiter='&', encode=True, encode_dot_in_keys=False, encode_values_only=False, format=<Format.RFC3986: format_name='RFC3986', formatter=<function Formatter.rfc3986>>, filter=None, skip_nulls=False, serialize_date=<function EncodeUtils.serialize_date>, encoder=<function EncodeOptions.encoder.<locals>.<lambda>>, strict_null_handling=False, comma_round_trip=None, sort=None)) str
Stringify a Python value into a query string.
- Parameters:
value – The object to encode. Accepted shapes: * Mapping -> encoded as-is. * Sequence (list/tuple) -> treated as an object with string indices. * Other/None -> treated as empty input.
options – Encoding behavior (parity with the Node.js qs API).
- Returns:
The encoded query string (possibly prefixed with “?” if requested), or an empty string when there is nothing to encode.
Notes
Caller input is not mutated. When a mapping is provided it is deep-copied; sequences are projected to a temporary mapping.
If a callable filter is provided, it can transform the root object.
If an iterable filter is provided, it selects which root keys to emit.
- qs_codec.encode(value: ~typing.Any, options: ~qs_codec.models.encode_options.EncodeOptions = EncodeOptions(allow_dots=False, add_query_prefix=False, allow_empty_lists=False, indices=None, list_format=<ListFormat.INDICES: list_format_name='INDICES', generator=<function ListFormatGenerator.indices>>, charset=<Charset.UTF8: encoding='utf-8'>, charset_sentinel=False, delimiter='&', encode=True, encode_dot_in_keys=False, encode_values_only=False, format=<Format.RFC3986: format_name='RFC3986', formatter=<function Formatter.rfc3986>>, filter=None, skip_nulls=False, serialize_date=<function EncodeUtils.serialize_date>, encoder=<function EncodeOptions.encoder.<locals>.<lambda>>, strict_null_handling=False, comma_round_trip=None, sort=None)) str [source]
Stringify a Python value into a query string.
- Parameters:
value – The object to encode. Accepted shapes: * Mapping -> encoded as-is. * Sequence (list/tuple) -> treated as an object with string indices. * Other/None -> treated as empty input.
options – Encoding behavior (parity with the Node.js qs API).
- Returns:
The encoded query string (possibly prefixed with “?” if requested), or an empty string when there is nothing to encode.
Notes
Caller input is not mutated. When a mapping is provided it is deep-copied; sequences are projected to a temporary mapping.
If a callable filter is provided, it can transform the root object.
If an iterable filter is provided, it selects which root keys to emit.
- qs_codec.load(value: str | Mapping[str, Any] | None, options: DecodeOptions | None = None) Dict[str, Any]
Decode a query string (or a pre-tokenized mapping) into a nested
Dict[str, Any]
.- Parameters:
value – Either a raw query string (
str
) or an already-parsed mapping (Mapping[str, Any]
). Passing a mapping is useful in tests or when a custom tokenizer is used upstream.options –
DecodeOptions
controlling delimiter, duplicates policy, list & depth limits, dot-notation, decoding charset, and more.
- Returns:
A freshly-allocated mapping containing nested dicts/lists/values.
- Return type:
Dict[str, Any]
- Raises:
ValueError – If
value
is neitherstr
norMapping
, or when limits are violated underraise_on_limit_exceeded=True
.
Notes
Empty/falsey
value
returns an empty dict.When the number of top-level tokens exceeds
list_limit
andparse_lists
is enabled, the parser temporarily disables list parsing for this invocation to avoid quadratic work. This mirrors the behavior of other ports and keeps large flat query strings efficient.
- qs_codec.loads(value: str | None, options: DecodeOptions | None = None) Dict[str, Any] [source]
Alias for
decode
. Decodes a query string into aDict[str, Any]
.Use
decode
if you want to pass aDict[str, Any]
.