Skip to content

Commit d195992

Browse files
authored
Merge pull request #14 from modern-python/chore/release-0.1.0-prep
chore: prep 0.1.0 release
2 parents 204d463 + e9c5c97 commit d195992

6 files changed

Lines changed: 791 additions & 53 deletions

File tree

.github/workflows/publish.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: Publish Package
2+
3+
on:
4+
release:
5+
types:
6+
- published
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: extractions/setup-just@v2
14+
- uses: astral-sh/setup-uv@v3
15+
- run: just publish
16+
env:
17+
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}

CHANGELOG.md

Lines changed: 0 additions & 29 deletions
This file was deleted.

CONTRIBUTING.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ just test # pytest with coverage
1818
2. **Branch from `main`**, use a descriptive name (`feat/retry-budget-jitter`, `fix/transport-cancel-leak`).
1919
3. **Run `just lint` and `just test`** locally before pushing. CI will reject changes that fail either.
2020
4. **Add tests** for any code change. Property-based tests (via Hypothesis) are required for concurrency-sensitive code (retry budget, bulkhead, retry interleaving).
21-
5. **Update `CHANGELOG.md`** in the `Unreleased` section.
22-
6. **Open a pull request** against `main`. PR titles use conventional-commits style (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`).
21+
5. **Open a pull request** against `main`. PR titles use conventional-commits style (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`).
2322

2423
## Code style
2524

README.md

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
[![Python versions](https://img.shields.io/pypi/pyversions/httpware.svg)](https://pypi.org/project/httpware/)
66
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
77

8-
**Resilience-first async HTTP client framework for Python.**
8+
**Async HTTP client framework for Python.**
99

10-
`httpware` is to Python what Polly is to .NET and resilience4j is to the JVM — a canonical resilience-first HTTP framework. The public API is transport-agnostic (the underlying client is `httpx2` by default, sitting behind a swappable `Transport` protocol). Retries, timeouts, bulkheads, and a Finagle-style **retry budget** ship as composable middleware. Tests use a `RecordedTransport` and never see the underlying client.
10+
`httpware` is a typed, async HTTP client library built on `httpx2` with a protocol-based seam so the transport is swappable. Middleware composes via an onion model. Pydantic and msgspec response decoding ship out of the box. `RecordedTransport` replaces respx for transport-level tests.
1111

12-
> **Status:** Pre-1.0. Public API is subject to change between minor releases until v1.0. See [CHANGELOG.md](./CHANGELOG.md).
12+
> **Status:** Pre-1.0 (0.1.0 alpha). Public API is subject to change between minor releases until v1.0. Resilience middleware (retry / timeout / bulkhead), streaming, and observability are not yet shipped — track progress on GitHub.
1313
1414
## Install
1515

@@ -20,12 +20,11 @@ pip install httpware
2020
Optional extras:
2121

2222
```bash
23-
pip install httpware[msgspec] # msgspec ResponseDecoder
24-
pip install httpware[otel] # OpenTelemetry instrumentation
25-
pip install httpware[niquests] # niquests transport
26-
pip install httpware[all] # all of the above
23+
pip install httpware[msgspec] # MsgspecDecoder
2724
```
2825

26+
(`otel`, `niquests`, and `all` extras are declared but their integrations have not shipped yet.)
27+
2928
## Quickstart
3029

3130
```python
@@ -44,25 +43,19 @@ async def main() -> None:
4443
print(user.name)
4544
```
4645

47-
## Highlights
48-
49-
- **Transport-agnostic API.** No `httpx2` symbols leak through `httpware`. Swap to a different backend with one constructor argument.
50-
- **Onion middleware** with phase shortcuts (`@before_request`, `@after_response`, `@on_error`). Built-in middleware: `Retry`, `RetryBudget`, `Bulkhead`, `Timeout`, `Observability`.
51-
- **Retry budget by default** — token-bucket admission control (Finagle defaults). Caps retry storms before they happen.
52-
- **Pluggable validation.** Default pydantic decoder with cached `TypeAdapter`; msgspec decoder via extras; bring your own.
53-
- **`RecordedTransport` for tests.** A 3-line fixture replaces respx routes and transport-level mocking.
54-
- **Status-keyed exceptions** with plain fields (`status: int`, `body: bytes`, `headers`, `json`). No transport exception types in user code.
55-
- **First-class OpenTelemetry** instrumentation via `httpware[otel]`.
56-
57-
## Documentation
46+
## What ships in 0.1.0
5847

59-
Full docs (in progress): https://httpware.readthedocs.io
48+
- **`AsyncClient`** — eight HTTP method shortcuts (`get`, `post`, `put`, `patch`, `delete`, `head`, `options`, `request`) with typed `response_model` overloads; per-call overrides for `headers`, `params`, `cookies`, `timeout`, `json`, `content`; httpx-style `base_url` join; `with_options(...)` returns a view sharing the same transport.
49+
- **Transport-agnostic seam.** `httpx2` is confined to `httpware.transports.httpx2.Httpx2Transport`. Implement the `Transport` protocol to swap backends.
50+
- **Middleware foundation.** `Middleware` protocol, `Next` type alias, recursive-closure `compose()` chain composition, and phase decorators (`@before_request`, `@after_response`, `@on_error`).
51+
- **Pluggable response decoding.** `PydanticDecoder` (default) with cached `TypeAdapter`; `MsgspecDecoder` via `httpware[msgspec]`.
52+
- **`RecordedTransport`** — built-in test double with a route table, observed-request list, and `aclose_calls` counter.
53+
- **Status-keyed exception hierarchy**`StatusError`, 4xx / 5xx subclasses, plain typed fields (`status: int`, `body: bytes`, `headers`, `json`, `request_method`, `request_url`). Pickleable; userinfo redacted in `__repr__`.
54+
- **No `httpx2` exception types** leak through `httpware`. The transport seam maps them to `httpware` exceptions.
6055

6156
## Part of `modern-python`
6257

63-
Browse the full list of templates and libraries in
64-
[`modern-python`](https://github.com/modern-python) — see the org profile for the
65-
categorized index.
58+
Browse the full list of templates and libraries in [`modern-python`](https://github.com/modern-python) — see the org profile for the categorized index.
6659

6760
## License
6861

0 commit comments

Comments
 (0)