Typed, resilient HTTP clients for Python, sync and async.
Why httpware
- A 4xx or 5xx response raises an exception named after its status, such as
NotFoundErrorfor 404 orRateLimitedErrorfor 429. All of them subclasshttpware.StatusError, so you never callraise_for_status(). response_model=Userdecodes the body into your pydantic or msgspec type. If no installed decoder handles the type, the call fails before the request is sent.- Retry with a retry budget, bulkhead, circuit breaker, and timeout ship as middleware you compose per client.
httpware is a thin layer over httpx2: requests and responses are plain
httpx2.Request and httpx2.Response objects.
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 goes to pydantic, Struct to msgspec
pip install httpware[otel] # OpenTelemetry span events
pip install httpware[all] # pydantic, msgspec, and 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 works the same way: use Client instead of AsyncClient, and drop await and 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: first requests, client options, streaming.
- Resilience: retry and retry budget, bulkhead, circuit breaker, timeout.
- Errors: the exception tree and how to catch it.
- Decoders: typed response bodies and custom decoders.
- Middleware: writing your own (auth, tracing, request IDs).
- Observability: logger and event names, OpenTelemetry wiring.
- Testing: injecting
httpx2.MockTransport. - Recipes: DI wiring, phase decorators, Link header pagination.
🗒️ Release notes · 📦 PyPI · 📝 License
Part of modern-python
Browse the full list of templates and libraries in
modern-python; the org profile has the categorized index.
Metadata
Release files for httpware 0.22.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| httpware-0.22.0.tar.gz | 42.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| httpware-0.22.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 94.4 kB
Release files / httpware-0.22.0.tar.gz
| Download URL | httpware-0.22.0.tar.gz |
|---|---|
| Size | 42.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1e2e565ed493fa3456c0c0d5819825a01f9d5a5676f97d6a1ed1e38235493981
|
|
BLAKE2b-256 checksum How to use checksums |
28090206ee5a53e5b4c0fbf619cc996ac278cf158af4e6c9eb9d1173c164c5c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","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.22.0-py3-none-any.whl
| Download URL | httpware-0.22.0-py3-none-any.whl |
|---|---|
| Size | 51.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ef50d63fd5d130169fd2feab5d77e0e77d29e99d338fb75033cd8180c0a04bed
|
|
BLAKE2b-256 checksum How to use checksums |
7a799a1dea6ede7631fa16e4070951e59973b35d98edc19d4ae3f54b212aa496
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","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}
|
Security for httpware 0.22.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.