-`httpware` is a thin opinionated wrapper around `httpx2`. It re-exports `httpx2.Request` and `httpx2.Response` as the public request/response surface and adds three things on top: typed response decoding (via a `ResponseDecoder` protocol; pydantic and msgspec are both opt-in extras as of 0.3.0), a middleware chain composed at client construction, and a status-keyed exception tree raised automatically on 4xx and 5xx. As of 0.9.0, both clients take `decoders: Sequence[ResponseDecoder] | None = None` (a *list*, not a single instance) and dispatch via each decoder's `can_decode(model)` predicate; the default resolves against installed extras (pydantic-first when both present) and `AsyncClient()` / `Client()` no longer raise on missing extras. A new `MissingDecoderError` (sibling of `DecodeError` under `ClientError`) fires before the HTTP call when `response_model=` is set but no registered decoder claims the model. As of 0.4.0, the package ships a small resilience suite under `httpware.middleware.resilience` — a `Retry` middleware with a Finagle-style `RetryBudget`, plus a `Bulkhead` concurrency limiter — composed via the standard middleware chain. As of 0.5.0, `AsyncClient.stream()` provides a context-manager API for chunked response bodies; it bypasses the middleware chain by design (see planning/archive/specs/2026-06-05-streaming-design.md). As of 0.6.0, `Retry` and `Bulkhead` emit operational events via stdlib `logging` records (`httpware.retry` / `httpware.bulkhead` loggers) and — when `opentelemetry-api` is installed — OpenTelemetry span events on the active span. As of 0.7.0, the first-cut user-docs surface is live at <https://httpware.readthedocs.io/> (Middleware, Resilience, Errors, Testing guides) and Epic 3 is closed.
0 commit comments