Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions dataretrieval/waterdata/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,15 +316,25 @@ def _cql2_param(args: dict[str, Any]) -> str:
Returns
-------
str
JSON string representation of the CQL2 query.
Compact JSON string representation of the CQL2 query.

Notes
-----
Serialized with the tightest separators (no indentation or
whitespace). The body counts against the server's ~8 KB request-size
limit and against :func:`chunking._request_bytes` when planning
chunks, so every saved byte fits more values per POST: compact
encoding roughly halves the per-value cost versus pretty-printing,
which roughly doubles how many monitoring-location ids fit in one
sub-request and so halves the chunk count for large id lists.
"""
filters = []
for key, values in args.items():
filters.append({"op": "in", "args": [{"property": key}, values]})

query = {"op": "and", "args": filters}

return json.dumps(query, indent=4)
return json.dumps(query, separators=(",", ":"))


def _default_headers():
Expand Down
7 changes: 7 additions & 0 deletions tests/waterdata_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ def test_construct_api_requests_monitoring_locations_post():
assert req.method == "POST"
assert req.headers["Content-Type"] == "application/query-cql-json"

# Body is serialized compactly (tight separators, no whitespace): the
# body counts against the server's ~8 KB request-size cap and the
# chunk planner's byte budget, so pretty-printing would needlessly
# halve how many ids fit per sub-request and double the chunk count.
raw = req.content.decode()
assert "\n" not in raw and ", " not in raw and ": " not in raw

body = json.loads(req.content)
# Top-level shape: AND over a list of per-param predicates.
assert body["op"] == "and"
Expand Down
Loading