Skip to content

Commit 241c34b

Browse files
lesnik512claude
andcommitted
chore(release): 0.12.0 — per-verb *_with_response siblings
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c13685a commit 241c34b

2 files changed

Lines changed: 60 additions & 4 deletions

File tree

planning/deferred.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ As of 0.7.0, all planned epics (3, 4, 5, 6) are closed — see the [change Index
66

77
## Open
88

9-
### Client API surface
10-
11-
- **Per-verb-with-response siblings** (`get_with_response`, `post_with_response`, `request_with_response`) — the v0.8.2 spec deliberately ships only `send_with_response`; the verb-method shape would add ~400 LOC of overload boilerplate per side for a pattern (response headers + typed body) that's almost always paired with a GET and `build_request`. Revisit if a concrete consumer demand surfaces. (`src/httpware/client.py`)
12-
139
### Resilience
1410

1511
- **CircuitBreaker v2 — rolling-window / failure-rate mode** (`src/httpware/middleware/resilience/circuit_breaker.py`) — the 0.10.0 breaker ships only the *classic consecutive-failure* model (open after N counted failures in a row; any success resets the streak). That can't catch *partial* degradation (e.g. a steady 50% error rate that alternates success/fail never trips). Deferred to v2 in the 0.10.0 spec; the config was shaped so a rate mode is purely additive (a new opt-in `failure_rate_threshold` + window + `minimum_calls`, with classic remaining the default). Demand-gated: build when someone needs rate-based tripping.

planning/releases/0.12.0.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# httpware 0.12.0 — per-verb *_with_response siblings
2+
3+
**Minor release. Additive only — no breaking changes.**
4+
5+
This release adds ergonomic per-verb shortcuts for the common pattern of needing
6+
both the raw `httpx2.Response` (headers, status, request URL) and a typed body in
7+
a single call — without having to pair `build_request(...)` with
8+
`send_with_response(...)`.
9+
10+
## New public names
11+
12+
Six methods on both `AsyncClient` and `Client`:
13+
14+
```python
15+
from httpware import AsyncClient
16+
17+
client = AsyncClient(base_url="https://api.example.com", decoders=[...])
18+
19+
# One call — response metadata and typed body together
20+
response, users = await client.get_with_response(
21+
"/users", params={"page": 2}, response_model=list[User]
22+
)
23+
next_url = response.headers.get("Link")
24+
etag = response.headers.get("ETag")
25+
```
26+
27+
| Method | Verb |
28+
|---|---|
29+
| `get_with_response` | GET |
30+
| `post_with_response` | POST |
31+
| `put_with_response` | PUT |
32+
| `patch_with_response` | PATCH |
33+
| `delete_with_response` | DELETE |
34+
| `request_with_response` | any |
35+
36+
## Details
37+
38+
**Signature:** each method requires `response_model` (keyword-only) and returns
39+
`tuple[httpx2.Response, T]`. All other kwargs (`params`, `headers`, `json`,
40+
`content`, `timeout`, …) pass through to `httpx2` unchanged — identical to the
41+
non-`_with_response` siblings.
42+
43+
**Use case:** response metadata alongside a typed body — Link-header pagination,
44+
ETag caching, rate-limit reads (`X-RateLimit-Remaining`), request URL logging on
45+
redirect. When you don't need the raw response, the existing `get` / `post` /
46+
… methods remain the preferred form.
47+
48+
**Scope:** no `head_with_response` or `options_with_response` — HEAD is
49+
bodiless and OPTIONS is rarely decoded. `request_with_response(method, url, …)`
50+
is the escape hatch for any other verb.
51+
52+
**Inherited behavior:** `MissingDecoderError` is raised *before* the HTTP call
53+
when no decoder claims the model type; `DecodeError` wraps a failure inside
54+
`decode()`. Both propagate unchanged through the new methods, identical to
55+
`send_with_response`.
56+
57+
## Shipped via
58+
59+
PR adding per-verb `*_with_response` siblings to `AsyncClient` and `Client`
60+
(`src/httpware/client.py`).

0 commit comments

Comments
 (0)