Typed, resilient HTTP clients for Python — typed errors, typed response bodies, and composable resilience (retry, bulkhead, circuit breaker), sync or async.
Why httpware
- Errors you can catch by name — a 404 raises
NotFoundError, a 429RateLimitedError, automatically; everything else bubbles up under onehttpware.StatusErrorbase. Noraise_for_status(), no status-code branching. - Typed response bodies —
response_model=Userdecodes the body straight to your pydantic or msgspec type; a missing decoder fails fast, before the request goes out. - Composable resilience — retry + retry-budget, bulkhead, circuit breaker,
and timeout as middleware over standard
httpx2.
Built on httpx2: httpware re-exports httpx2.Request/httpx2.Response and stays a thin wrapper, not a new HTTP abstraction.
Status: Pre-1.0. Public API is subject to change between minor releases until v1.0.
Install
pip install httpware # core only — no decoder
pip install httpware[pydantic] # + PydanticDecoder — BaseModel, dataclasses, primitives, generics
pip install httpware[msgspec] # + MsgspecDecoder — Struct, dataclasses, primitives, generics
pip install httpware[pydantic,msgspec] # both — BaseModel routes to pydantic, Struct to msgspec
pip install httpware[all] # everything (pydantic, msgspec, otel)
Quickstart
A typed GET against a live API (needs pip install httpware[pydantic]):
import asyncio
from httpware import AsyncClient
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
async def main() -> None:
async with AsyncClient(base_url="https://jsonplaceholder.typicode.com") as client:
user = await client.get("/users/1", response_model=User)
print(user.name) # Leanne Graham
asyncio.run(main())
The sync Client is identical — swap AsyncClient → Client and drop the await / async with. A 4xx/5xx response raises a typed StatusError; a malformed body raises DecodeError. Both subclass httpware.ClientError.
Documentation
Full guides live at httpware.modern-python.org:
- Quickstart & observability — resilience middleware, streaming, and the stable logger/event contract.
- Middleware — write your own (auth, tracing, request-ID propagation).
- Resilience — retry + retry-budget, bulkhead, circuit breaker, timeout.
- Errors — the exception tree and catching strategies.
- Testing —
httpx2.MockTransportinjection. - Recipes — DI wiring, phase-decorator patterns, link-header pagination.
🗒️ Release notes · 📦 PyPI · 📝 License
Part of modern-python
Browse the full list of templates and libraries in
modern-python — see the org profile for the categorized index.
Metadata
Release files for httpware 0.17.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| httpware-0.17.1.tar.gz | 37.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| httpware-0.17.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 85.8 kB
Release files / httpware-0.17.1.tar.gz
| Download URL | httpware-0.17.1.tar.gz |
|---|---|
| Size | 37.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1e3a6c62eafe427f43b27360c2468f64b3f178440858cbe4808da926d4a6a74a
|
|
BLAKE2b-256 checksum How to use checksums |
a3bab889e68c54574982d3be20a2d3d5075aada46aedeaf1a82d715ef1a117fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / httpware-0.17.1-py3-none-any.whl
| Download URL | httpware-0.17.1-py3-none-any.whl |
|---|---|
| Size | 48.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c66560fbf9acd01c6ed91c0e5c9ecb1b34ae560f54387602f5e93bdb058f1e37
|
|
BLAKE2b-256 checksum How to use checksums |
9b210910a23152265ad881510ee1038c57761ebe213cae3dd41f5cc797fc2cd9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.19 {"installer":{"name":"uv","version":"0.12.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|