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.
Release files for httpware 0.17.2
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.2.tar.gz | 37.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| httpware-0.17.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 86.1 kB
Release files / httpware-0.17.2.tar.gz
| Download URL | httpware-0.17.2.tar.gz |
|---|---|
| Size | 37.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
68a4458e8cd07f81b2b012ac754954f6d12fe84c4c33b196817c8a2a48c23be4
|
|
BLAKE2b-256 checksum How to use checksums |
dd4ab266ddc021d0f6477fd30b1b042cefcc3d815a61f7b9ebe8f9701d54df7c
|
| 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.2-py3-none-any.whl
| Download URL | httpware-0.17.2-py3-none-any.whl |
|---|---|
| Size | 48.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
428a5567cd2869c98f551722abc79eb47f0888c627d92953981d3ca139d35e11
|
|
BLAKE2b-256 checksum How to use checksums |
5cfde122dc362498e285fc0373c08b20363a82c7bfe6ed6ea65b65a7915815e3
|
| 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}
|