Metadata-Version: 2.4
Name: fast-querydict
Version: 0.1.0
Summary: Fast application/x-www-form-urlencoded parser for Django QueryDict, with optional html-json-forms nesting, in one pass
Author-email: David Raznick <kindly@gmail.com>
License-Expression: License :: OSI Approved :: MIT License
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# fast-querydict

A fast, entity-agnostic parser for `application/x-www-form-urlencoded` request
bodies, built for Django. One pass over the raw bytes yields both the flat data
(ready to become a real `django.http.QueryDict`) and, optionally, the generic
[html-json-forms](https://www.w3.org/TR/html-json-forms/) nesting of the same
body.

```python
import fast_querydict

grouped, nested = fast_querydict.parse(request.body, build_json=True)
# grouped -> {"units": ["a", "b"], "id": ["9"], ...}   raw, first-seen order
# nested  -> {"units": [{"capacity": "100"}], "id": "9", ...}  or None
```

* `grouped` is `{key: [value, ...]}` with **raw** values (percent- and
  `+`-decoded, *not* trimmed) in first-seen key order — exactly the internal
  storage of a `QueryDict`, so Python can adopt it with a single `dict.update`.
* `nested` is the html-json-forms nesting (`a[0][b]` → `{"a": [{"b": …}]}`),
  with single scalar values trimmed and `""` nulled, or `None` when
  `build_json` is false.

See `projects/fast_post.py` in the GEM project DB for the Django glue: a
`QueryDict` subclass carrying `.json`, and a pre-CSRF middleware that builds it
lazily on first `request.POST` access.

## Build / develop

```bash
cd fast_querydict
cargo test                 # pure-Rust logic tests (no Python needed)
maturin develop --release  # build + install into the active venv
```

The Python side imports it opportunistically and falls back to Django's own
parser if it is missing or fails to import, so it is safe to ship without it.

## Publish

Wheels are built and uploaded to PyPI by the **`publish-fast-querydict`** GitHub
Actions workflow (manylinux wheels + sdist via `PyO3/maturin-action`, uploaded
with `maturin upload` — the same approach as jsonlinesrust/flatterer). It is
manual / click-to-deploy: **Actions → publish-fast-querydict → Run workflow**.

One-time setup: add a PyPI API token as the repo secret `PYPI_API_TOKEN`. Bump
`version` in `Cargo.toml` before publishing a new release.

Consumers then install the prebuilt wheel — no Rust toolchain needed at deploy:

```bash
pip install fast-querydict
```

