Choosing an adapter¶
Short version: new async service → httpx. New sync service → httpx. Existing codebase → the adapter matching the SDK you already use. clientwright's job is to make that second answer safe — you keep your library and gain the engine.
The lineup¶
| Adapter | Flavors | Seam | The one-line story |
|---|---|---|---|
| httpx | async + sync | transport | the reference adapter; cleanest seam in the ecosystem |
| httpx2 | async + sync | transport | httpx's successor under Pydantic stewardship; same adapter surface, one import apart |
| aiohttp | async | client middleware | highest-throughput async stack; a few sharp edges the adapter files down |
| requests | sync | HTTPAdapter |
the lingua franca of sync Python; adapter closes its famous no-default-timeout hole |
| urllib3 | sync | urlopen |
the foundation layer; home of delegated retries |
Every adapter passes the same cross-adapter parity battery in CI: identical retry
counts, breaker behavior, deadline handling, redirect semantics and metric names
on identical scenarios. The differences that remain are declared — each page
below leads with its capability quirks, and
capabilities_matrix() gives you the same data as
code.
Switching adapters¶
Because the config is transport-free and the metric schema frozen, a migration between adapters is:
- change the extra in your dependency file,
- change the string in
build("aiohttp", ...), - rewrite the call sites from one SDK's API to the other's (clientwright does not hide this — you were always writing real SDK code),
- read
handle.reportunderon_unsupported="strict"and address what it says.
Dashboards, alerts, retry behavior and breaker tuning carry over untouched.
The experimental tier¶
tornado, aiosonic and niquests sit outside the parity guarantee: adapters
may exist or appear on demand, but they do not gate releases. (A note for
niquests specifically: its install replaces urllib3 in site-packages via a
.pth trick, which is why it will never be part of the all extra.)
Third-party adapters register with two import strings and join the same machinery:
import clientwright
clientwright.register_adapter(
"myhttp",
"my_pkg.adapter:MyHttpAdapter",
"my_pkg.capabilities:CAPABILITIES",
)
See Writing an adapter.