qs-codec

qs-codec

A query string encoding and decoding library for Python.

Ported from qs for JavaScript.

PyPI version PyPI downloads PyPI status Python version support PyPy support status PyPI format Code style Black Test Status CodeQL Status Publish Status Docs Status Code Coverage Codacy Quality OpenSSF Best Practices flake8 Status typing mypy linting pylint imports isort Security Status License Contributor Covenant GitHub Sponsors GitHub Repo stars

Highlights

  • Nested dictionaries & lists: foo[bar][baz]=qux{'foo': {'bar': {'baz': 'qux'}}}.

  • Multiple list formats: INDICES (a[0]=x), BRACKETS (a[]=x), REPEAT (a=x&a=y), COMMA (a=x,y) with optional comma round-trip.

  • Dot-notation: parse/encode keys like a.b=c as nested; option to encode dots in keys when using dot notation.

  • Charset handling: UTF-8 (default) and Latin-1; optional charset sentinel (utf8=✓) to auto-detect encoding.

  • Pluggable hooks: custom encoder/decoder callables; options to sort keys, filter output, and control percent-encoding (keys-only, values-only).

  • Nulls & empties: strict_null_handling and skip_nulls; support for empty lists/arrays when desired.

  • Dates: serialize_date for ISO 8601 or custom (e.g., UNIX timestamp).

  • Safety limits: configurable decode depth and encode max depth, parameter limit, and list element limit; optional strict-depth errors; duplicate-key strategies (combine/first/last).

  • Extras: numeric entity decoding (e.g. ☺ → ☺), alternate delimiters/regex, and query-prefix helpers.

Compatibility

  • CPython 3.8–3.14 (default tox envs).

  • PyPy 3.8–3.11 (run tox -e pypy3.8 through tox -e pypy3.11 locally; CI mirrors this matrix).

Usage

A simple usage example:

import qs_codec as qs

# Encoding
assert qs.encode({'a': 'b'}) == 'a=b'

# Decoding
assert qs.decode('a=b') == {'a': 'b'}

Compared with urllib.parse

Use urllib.parse.urlencode, parse_qs, and parse_qsl for conventional flat form data. urlencode does not recursively encode nested mappings. parse_qs groups values by name; parse_qsl instead preserves pair order and interleaved duplicates. Both parsers treat bracket expressions as literal keys and collapse a name-only token and an explicit empty value when blanks are retained. Use qs_codec for nested dictionaries and lists, Node qs interoperability, configurable duplicate and null semantics, or matching encode/decode support. See Thread safety for URL composition guidance.

Indices and tables


Other ports

Port

Repository

Package

Dart

techouse/qs

pub.dev version

Kotlin / JVM + Android AAR

techouse/qs-kotlin

Maven Central version

Swift / Objective-C

techouse/qs-swift

Swift Package Manager version

.NET / C#

techouse/qs-net

NuGet version

Rust

techouse/qs_rust

crates.io version

Node.js (original)

ljharb/qs

npm version


Special thanks to the authors of qs for JavaScript: - Jordan Harband - TJ Holowaychuk