Skip to main content

Ultra-fast query string and url-encoded form-data parsers

Project description

Litestar Logo - Light Litestar Logo - Dark

Project Status
CI/CD Publish CI
Package PyPI - Version PyPI - Support Python Versions PyPI - Downloads
Community Reddit Discord Matrix Medium Twitter Blog
Meta Litestar Project License - MIT Litestar Sponsors linting - Ruff code style - Black

Fast Query Parsers

This library includes ultra-fast Rust based query string and urlencoded parsers. These parsers are used by Litestar, but are developed separately - and can of course be used separately.

[!IMPORTANT]
Starlite has been renamed to Litestar

Installation

pip install fast-query-parsers

Usage

The library exposes two function parse_query_string and parse_url_encoded_dict.

parse_query_string

This function is used to parse a query string into a list of key/value tuples.

from fast_query_parsers import parse_query_string

result = parse_query_string(b"value=1&value=2&type=dollar&country=US", "&")
# [("value", "1"), ("value", "2"), ("type", "dollar"), ("country", "US")]

The first argument to this function is a byte string that includes the query string to be parsed, the second argument is the separator used.

Benchmarks

Query string parsing is more than x5 times faster than the standard library:

stdlib parse_qsl parsing query string: Mean +- std dev: 2.86 us +- 0.03 us
.....................
parse_query_string parsing query string: Mean +- std dev: 916 ns +- 13 ns
.....................
stdlib parse_qsl parsing urlencoded query string: Mean +- std dev: 8.30 us +- 0.10 us
.....................
parse_query_string urlencoded query string: Mean +- std dev: 1.50 us +- 0.03 us

parse_url_encoded_dict

This function is used to parse a url-encoded form data dictionary and parse it into the python equivalent of JSON types.

from urllib.parse import urlencode

from fast_query_parsers import parse_url_encoded_dict

encoded = urlencode(
    [
        ("value", "10"),
        ("value", "12"),
        ("veggies", '["tomato", "potato", "aubergine"]'),
        ("nested", '{"some_key": "some_value"}'),
        ("calories", "122.53"),
        ("healthy", "true"),
        ("polluting", "false"),
        ("json", "null"),
    ]
).encode()

result = parse_url_encoded_dict(encoded, parse_numbers=True)

# result == {
#     "value": [10, 12],
#     "veggies": ["tomato", "potato", "aubergine"],
#     "nested": {"some_key": "some_value"},
#     "calories": 122.53,
#     "healthy": True,
#     "polluting": False,
#     "json": None,
# }

This function handles type conversions correctly - unlike the standard library function parse_qs. Additionally, it does not nest all values inside lists.

Note: the second argument passed to parse_url_encoded_dict dictates whether numbers should be parsed. If True, the value will be parsed into an int or float as appropriate, otherwise it will be kept as a string. By default the value of this arg is True.

Benchmarks

Url Encoded parsing is more than x2 times faster than the standard library, without accounting for parsing of values:

stdlib parse_qs parsing url-encoded values into dict: Mean +- std dev: 8.99 us +- 0.09 us
.....................
parse_url_encoded_dict parse url-encoded values into dict: Mean +- std dev: 3.77 us +- 0.08 us

To actually mimic the parsing done by parse_url_encoded_dict we will need a utility along these lines:

from collections import defaultdict
from contextlib import suppress
from json import loads, JSONDecodeError
from typing import Any, DefaultDict, Dict, List
from urllib.parse import parse_qsl


def parse_url_encoded_form_data(encoded_data: bytes) -> Dict[str, Any]:
    """Parse an url encoded form data into dict of parsed values"""
    decoded_dict: DefaultDict[str, List[Any]] = defaultdict(list)
    for k, v in parse_qsl(encoded_data.decode(), keep_blank_values=True):
        with suppress(JSONDecodeError):
            v = loads(v) if isinstance(v, str) else v
        decoded_dict[k].append(v)
    return {k: v if len(v) > 1 else v[0] for k, v in decoded_dict.items()}

With the above, the benchmarks looks like so:

python parse_url_encoded_form_data parsing url-encoded values into dict: Mean +- std dev: 19.7 us +- 0.1 us
.....................
parse_url_encoded_dict parsing url-encoded values into dict: Mean +- std dev: 3.69 us +- 0.03 us

Contributing

All contributions are of course welcome!

Repository Setup

  1. Run cargo install to setup the rust dependencies and poetry install to setup the python dependencies.
  2. Install the pre-commit hooks with pre-commit install (requires pre-commit).

Building

Run poetry run maturin develop --release --strip to install a release wheel (without debugging info). This wheel can be used in tests and benchmarks.

Benchmarking

There are basic benchmarks using pyperf in place. To run these execute poetry run python benchrmarks.py.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fast_query_parsers-1.0.3.tar.gz (25.3 kB view details)

Uploaded Source

Built Distributions

fast_query_parsers-1.0.3-cp38-abi3-win_amd64.whl (689.7 kB view details)

Uploaded CPython 3.8+ Windows x86-64

fast_query_parsers-1.0.3-cp38-abi3-win32.whl (646.4 kB view details)

Uploaded CPython 3.8+ Windows x86

fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_x86_64.whl (967.7 kB view details)

Uploaded CPython 3.8+ musllinux: musl 1.2+ x86-64

fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_i686.whl (965.4 kB view details)

Uploaded CPython 3.8+ musllinux: musl 1.2+ i686

fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_armv7l.whl (963.0 kB view details)

Uploaded CPython 3.8+ musllinux: musl 1.2+ ARMv7l

fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_aarch64.whl (911.0 kB view details)

Uploaded CPython 3.8+ musllinux: musl 1.2+ ARM64

fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (828.6 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ x86-64

fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl (940.0 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ s390x

fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl (969.5 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ ppc64le

fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl (1.0 MB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ ppc64

fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (729.9 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ ARMv7l

fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (764.0 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ ARM64

fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl (863.1 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.5+ i686

fast_query_parsers-1.0.3-cp38-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (1.5 MB view details)

Uploaded CPython 3.8+ macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

fast_query_parsers-1.0.3-cp38-abi3-macosx_10_7_x86_64.whl (766.2 kB view details)

Uploaded CPython 3.8+ macOS 10.7+ x86-64

File details

Details for the file fast_query_parsers-1.0.3.tar.gz.

File metadata

  • Download URL: fast_query_parsers-1.0.3.tar.gz
  • Upload date:
  • Size: 25.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.12

File hashes

Hashes for fast_query_parsers-1.0.3.tar.gz
Algorithm Hash digest
SHA256 5200a9e02997ad51d4d76a60ea1b256a68a184b04359540eb6310a15013df68f
MD5 07433cb8c524c3248082d6ca58056bb0
BLAKE2b-256 dd203a00b889a196e8dc5bede2f168d4a14edc8b5bccc3978a9f497f0f863e79

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 21ae5f3a209aee7d3b84bdcdb33dd79f39fc8cb608b3ae8cfcb78123758c1a16
MD5 4227a62ca39b2f24853031aba9cd8f8c
BLAKE2b-256 ae4b07fe4d7b5c458bdde9b0bfd8e8cb5762341af6c9727b43c2331c0cb0dbc3

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-win32.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-win32.whl
Algorithm Hash digest
SHA256 14b3fab7e9a6ac1c1efaf66c3fd2a3fd1e25ede03ed14118035e530433830a11
MD5 51fc7f0fc5553da35d1f34140573adfa
BLAKE2b-256 0ae321bc18edc003b54a2069eb854b9f92cacb5acc99e03c609487a23a673755

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 a70d4d8852606f2dd5b798ab628b9d8dc6970ddfdd9e96f4543eb0cc89a74fb5
MD5 0482edf0735f6243a843e073aa358429
BLAKE2b-256 ea58942327d3f2694b8f1a2fffaaaef1cc3147571852473a80070ebd6156a62e

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_i686.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_i686.whl
Algorithm Hash digest
SHA256 7ca6be04f443a1b055e910ccad01b1d72212f269a530415df99a87c5f1e9c927
MD5 e883b622e3fc6e5e3944560ed4cb300f
BLAKE2b-256 6fa9132572b9f40c2635fdedb7a1cb6cedd9c880f8ffbbfdd6215ee493bb6936

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 3a6377eb0c5b172fbc77c3f96deaf1e51708b4b96d27ce173658bf11c1c00b20
MD5 9167cd76ad14c82075aa1082985ce8b4
BLAKE2b-256 f8b8bf5e44588f6ebd81d0c53ba49c79999dc54cb0fe81ad6dde6fed2cd45b56

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 5736d3c32d6ba23995fa569fe572feabcfcfc30ac9e4709e94cff6f2c456a3d1
MD5 a94b6e4b5fa5f5427007ad635f1ba1b2
BLAKE2b-256 05d45eb8c9d400230b9a45a0ce47a443e9fe37b0902729f9440adef677af1f0d

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 55a30b7cee0a53cddf9016b86fdad87221980d5a02a6126c491bd309755e6de9
MD5 bd10eb28ba9f7f66c8a36da75e776f70
BLAKE2b-256 7434950b6d799839c11e93566aef426b67f0a446c4906e45e592026fde894459

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 e947e7251769593da93832a10861f59565a46149fa117ebdf25377e7b2853936
MD5 cbef8c37368a7f9e21269112311cb956
BLAKE2b-256 c39f4dfa29d74276fa07c40689bfaa3b21d057249314aeb20150f0f41373d16d

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
Algorithm Hash digest
SHA256 6720505f2d2a764c76bcc4f3730a9dff69d9871740e46264f6605d73f9ce3794
MD5 36ae3c2e97932caf0bd78412c1e14c69
BLAKE2b-256 419b5a42ddd23b85357be6764e14daa607d9b16bc6a395aae2c1cc2077e0a11d

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl
Algorithm Hash digest
SHA256 0bdcc0ddb4cc69d823c2c0dedd8f5affc71042db39908ad2ca06261bf388cac6
MD5 59e1727961d4b93bd5185b2b0a868ca5
BLAKE2b-256 f0357a9a0c50588033edd9efba48f21e251dfcf77eaec2aff470988f622fbd3a

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 a6e3d816c572a6fad1ae9b93713b2db0d3db6e8f594e035ad52361d668dd94a8
MD5 48b551b0d4bde10f28fd687662e1acbd
BLAKE2b-256 75068861197982909bec00b180527df1e0e9791715271bfb84c8be389b6bf077

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 66630ad423b5b1f5709f82a4d8482cd6aa2f3fa73d2c779ff1877f25dee08d55
MD5 129d2abc2f938c802290204b94e7373f
BLAKE2b-256 515bb10719598dbd14201271efd0b950c6a09efa0a3f6246fec3c192c6b7a8d2

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm Hash digest
SHA256 9bc2b457caa38371df1a30cfdfc57bd9bfdf348367abdaf6f36533416a0b0e93
MD5 1cc98d830ea1d9c1daa3ca6dce9ebcf8
BLAKE2b-256 81a8ee95263abc9806c81d77be8a3420d1f4dde467a10030dde8b0fa0e63f700

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 42f26875311d1b151c3406adfa39ec2db98df111a369d75f6fa243ec8462f147
MD5 0c46642d34535b6fc2f58b96304b724a
BLAKE2b-256 c521c8c160f61a740efc4577079eb5747a6b2cb8d1168a84a0bfda6044113768

See more details on using hashes here.

File details

Details for the file fast_query_parsers-1.0.3-cp38-abi3-macosx_10_7_x86_64.whl.

File metadata

File hashes

Hashes for fast_query_parsers-1.0.3-cp38-abi3-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 afbf71c1b4398dacfb9d84755eb026f8e759f68a066f1f3cc19e471fc342e74f
MD5 6dd4cdb26328738f7750800d44ad0a27
BLAKE2b-256 43184179ac7064b4216ca42f2ed6f74e71254454acf2ec25ce6bb3ffbfda4aa6

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page