Repository navigation
feat(rest): pluggable JSON loader + plumb extra_headers through resources (#260, #253) - #288
Conversation
Mirrors ws_json_loads. Setting KalshiConfig.rest_json_loads to orjson.loads cuts parsing on list endpoints (markets.list_all, trades.list_all, fcm.orders) 2-3x while keeping stdlib as the zero-dep default. The shared _load_json helper on Sync/AsyncResource calls config.rest_json_loads(response.content) when set, falling back to httpx's response.json() otherwise. Threaded through every helper: _get, _post, _post_json, _put, _delete, _delete_with_body, _delete_with_body_json (sync + async). Also widens base helpers to accept extra_headers — #253 plumbs it through resource methods next. Closes #260
Per-request extra_headers (Idempotency-Key, X-Request-ID, tracing headers) used to require reaching into client._transport.request(...) — making the feature private despite being documented as additive. Every public method on every Sync/AsyncResource subclass now takes extra_headers: dict[str, str] | None = None and forwards it through the base _get/_post/_put/_delete/_list/_list_all helpers to the transport. Auth-header precedence is preserved: KALSHI-ACCESS-* always wins over extra_headers (transport-level merge order: config_extra < extra_headers < body_headers < signed_auth) — verified by tests. Contract drift test (tests/test_contracts.py) excludes extra_headers globally — it's an SDK-meta kwarg with no OpenAPI counterpart. 302 method signatures updated across 19 resource files; codemod via libcst kept docstrings, overloads, and existing kwargs intact. ruff format normalized line breaks introduced by the kwarg. Tests: * TestOrders/TestMarkets/TestPortfolio assert the header reaches the wire and that KALSHI-ACCESS-* spoofs are rejected. * test_every_public_method_accepts_extra_headers parametrically enumerates every Sync/AsyncResource subclass via reflection. Closes #253
Code Review — PR #288: Pluggable JSON loader + per-request
|
| Area | Coverage |
|---|---|
rest_json_loads sync GET/POST |
✓ test_rest_json_loader.py |
rest_json_loads async GET |
✓ |
rest_json_loads default (stdlib) |
✓ |
extra_headers wire delivery (orders, markets, portfolio) |
✓ test_extra_headers_plumbing.py |
| Auth header spoof prevention | ✓ (three independent resources) |
Every public method has extra_headers kwarg |
✓ parametric test |
ws_json_loads / ws_json_dumps config additions |
Not in new tests (pre-existing?) |
If ws_json_loads/ws_json_dumps are new additions (the config diff shows them), confirm they have test coverage elsewhere.
Contract drift tests
The exclusion in test_contracts.py is the right call:
sdk_params.discard("extra_headers")extra_headers is an SDK meta-kwarg with no OpenAPI counterpart, so excluding it globally rather than adding per-endpoint EXCLUSIONS entries is cleaner. The comment explains the rationale. ✓
Summary
- No bugs found
- Auth protection is implemented correctly and tested
- The approach is minimal and consistent with project conventions
- Two minor notes worth considering before merge: (1) document the type contract on custom loaders in the docstring for
_load_json, (2) consider whetherws_json_loads/ws_json_dumpsneed test coverage in this PR or can follow separately
Closes #260
Closes #253
Part of #273 (post-v2.4 audit), Wave 2.2.