Skip to content

feat: forward every httpx2 client option to the owned client - #148

Merged
lesnik512 merged 2 commits into
mainfrom
feat/forward-httpx2-client-options
Oct 1, 2026
Merged

lesnik512 merged 2 commits into
mainfrom
feat/forward-httpx2-client-options

Conversation

@lesnik512

@lesnik512 lesnik512 commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Problem

AsyncClient and Client forwarded only seven httpx2 client keywords (base_url, headers, params, cookies, timeout, limits, auth). Anything else, most often verify for a custom CA, meant building the httpx2 client by hand and passing it as httpx2_client=. That cost more than one argument:

  • every other option had to move onto the hand-built client, because combining them raised TypeError
  • httpware stopped owning the client, so close()/aclose() and the context manager no longer closed it

Change

The constructors take **httpx2_options: Unpack[_AsyncClientOptions] (_ClientOptions for sync) and forward every httpx2 client keyword to the client they build and own. The seven existing options keep their types, so call sites are unchanged. Three per-option helpers are replaced by one _select_httpx2_options.

AsyncClient(base_url="https://internal.example", verify=ssl.create_default_context(cafile=...))
AsyncClient(transport=httpx2.MockTransport(handler))  # still owned and closed by httpware

A named parameter per option was rejected because each one had to be listed three times (signature, conflict check, assembly). An untyped httpx2_client_kwargs= dict was rejected because it gives up type checking.

Refused and restricted options

  • cert is refused: httpx2 deprecates it in favour of an ssl.SSLContext passed as verify. verify=<str> is excluded from the type for the same reason.
  • event_hooks is refused: hooks run below the middleware chain, so an httpx2.HTTPError raised in a hook reaches retry and the circuit breaker as TransportError. Middleware covers the use case.
  • follow_redirects=True with max_response_body_bytes raises ValueError, because httpx2 reads intermediate redirect bodies with an unbounded response.read() (up to max_redirects).
  • Unset values (None, empty base_url) are dropped, not forwarded. To httpware, timeout=None has always meant "httpx2 default (5s)"; to httpx2 it means "no timeout". Forwarding it would silently remove timeouts.

Type checking

A spike showed ty 0.0.84 checks value types under Unpack[TypedDict] but does not flag unknown keys (pyright and mypy do). The constructor therefore rejects unknown keys at runtime.

Behaviour change

A caller-provided httpx2_client with follow_redirects=True combined with max_response_body_bytes now raises ValueError. It was accepted before, but the cap did not cover redirect bodies.

Docs

  • docs/index.md: option forwarding, with a verify example and when to use httpx2_client=
  • docs/testing.md: mock with transport= instead of a hand-built httpx2_client=
  • docs/errors.md: the redirect restriction
  • AGENTS.md: the testing pattern

Tests

tests/test_client_options.py, written first, covers both worlds:

  • every option reaches the owned httpx2 client
  • unset values are dropped
  • each option conflicts with httpx2_client=
  • unsupported keys raise TypeError
  • the redirect/cap rule, on owned and caller-provided clients
  • transport= keeps the client owned
  • a drift test that fails when an httpx2 upgrade adds a constructor keyword that is neither forwarded nor refused

Tests for the deleted helpers were removed. Full suite (955 passed, 100% coverage), ruff, ty, eof-fixer and mkdocs build --strict pass locally.

AsyncClient and Client forwarded only seven httpx2 client keywords, so
setting verify (or proxy, http2, transport, ...) meant building the httpx2
client by hand and closing it yourself. Every option is now forwarded,
typed via Unpack[TypedDict]; cert and event_hooks are refused, and
follow_redirects=True with max_response_body_bytes raises ValueError.
@lesnik512
lesnik512 merged commit 838b95c into main Oct 1, 2026
13 checks passed
@lesnik512
lesnik512 deleted the feat/forward-httpx2-client-options branch October 1, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant