httpware 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httpware
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Resilience-first async HTTP client framework for Python
5
5
  Keywords: http,async,client,resilience,retry,circuit-breaker,middleware,httpx,pydantic
6
6
  Author: Artur Shiriev
@@ -16,9 +16,8 @@ Classifier: Topic :: Internet :: WWW/HTTP
16
16
  Classifier: Framework :: AsyncIO
17
17
  Requires-Dist: httpx2>=2.0.0,<3.0
18
18
  Requires-Dist: pydantic>=2.0,<3.0
19
- Requires-Dist: httpware[msgspec,otel,niquests] ; extra == 'all'
19
+ Requires-Dist: httpware[msgspec,otel] ; extra == 'all'
20
20
  Requires-Dist: msgspec>=0.18 ; extra == 'msgspec'
21
- Requires-Dist: niquests>=3.18 ; extra == 'niquests'
22
21
  Requires-Dist: opentelemetry-api>=1.20 ; extra == 'otel'
23
22
  Requires-Dist: opentelemetry-sdk>=1.20 ; extra == 'otel'
24
23
  Requires-Python: >=3.11, <4
@@ -26,7 +25,6 @@ Project-URL: repository, https://github.com/modern-python/httpware
26
25
  Project-URL: docs, https://httpware.readthedocs.io
27
26
  Provides-Extra: all
28
27
  Provides-Extra: msgspec
29
- Provides-Extra: niquests
30
28
  Provides-Extra: otel
31
29
  Description-Content-Type: text/markdown
32
30
 
@@ -39,9 +37,9 @@ Description-Content-Type: text/markdown
39
37
 
40
38
  **Async HTTP client framework for Python.**
41
39
 
42
- `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.
40
+ `httpware` is a typed, async HTTP client library with a protocol-based seam so the transport is swappable (`httpx2` ships as the default). Middleware composes via an onion model. Pydantic and msgspec response decoding ship out of the box. `RecordedTransport` replaces `respx` for transport-level tests.
43
41
 
44
- > **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.
42
+ > **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.
45
43
 
46
44
  ## Install
47
45
 
@@ -55,7 +53,7 @@ Optional extras:
55
53
  pip install httpware[msgspec] # MsgspecDecoder
56
54
  ```
57
55
 
58
- (`otel`, `niquests`, and `all` extras are declared but their integrations have not shipped yet.)
56
+ (`otel`, `niquests`, and `all` extras are declared; integrations have not shipped yet.)
59
57
 
60
58
  ## Quickstart
61
59
 
@@ -75,20 +73,12 @@ async def main() -> None:
75
73
  print(user.name)
76
74
  ```
77
75
 
78
- ## What ships in 0.1.0
76
+ ## 📚 [Documentation](https://httpware.readthedocs.io)
79
77
 
80
- - **`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.
81
- - **Transport-agnostic seam.** `httpx2` is confined to `httpware.transports.httpx2.Httpx2Transport`. Implement the `Transport` protocol to swap backends.
82
- - **Middleware foundation.** `Middleware` protocol, `Next` type alias, recursive-closure `compose()` chain composition, and phase decorators (`@before_request`, `@after_response`, `@on_error`).
83
- - **Pluggable response decoding.** `PydanticDecoder` (default) with cached `TypeAdapter`; `MsgspecDecoder` via `httpware[msgspec]`.
84
- - **`RecordedTransport`** — built-in test double with a route table, observed-request list, and `aclose_calls` counter.
85
- - **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__`.
86
- - **No `httpx2` exception types** leak through `httpware`. The transport seam maps them to `httpware` exceptions.
78
+ ## 📦 [PyPI](https://pypi.org/project/httpware)
79
+
80
+ ## 📝 [License](./LICENSE)
87
81
 
88
82
  ## Part of `modern-python`
89
83
 
90
84
  Browse the full list of templates and libraries in [`modern-python`](https://github.com/modern-python) — see the org profile for the categorized index.
91
-
92
- ## License
93
-
94
- MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,54 @@
1
+ # httpware
2
+
3
+ [![Test](https://github.com/modern-python/httpware/actions/workflows/ci.yml/badge.svg)](https://github.com/modern-python/httpware/actions/workflows/ci.yml)
4
+ [![PyPI version](https://badge.fury.io/py/httpware.svg)](https://pypi.org/project/httpware/)
5
+ [![Python versions](https://img.shields.io/pypi/pyversions/httpware.svg)](https://pypi.org/project/httpware/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ **Async HTTP client framework for Python.**
9
+
10
+ `httpware` is a typed, async HTTP client library with a protocol-based seam so the transport is swappable (`httpx2` ships as the default). Middleware composes via an onion model. Pydantic and msgspec response decoding ship out of the box. `RecordedTransport` replaces `respx` for transport-level tests.
11
+
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.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ pip install httpware
18
+ ```
19
+
20
+ Optional extras:
21
+
22
+ ```bash
23
+ pip install httpware[msgspec] # MsgspecDecoder
24
+ ```
25
+
26
+ (`otel`, `niquests`, and `all` extras are declared; integrations have not shipped yet.)
27
+
28
+ ## Quickstart
29
+
30
+ ```python
31
+ from httpware import AsyncClient
32
+ from pydantic import BaseModel
33
+
34
+
35
+ class User(BaseModel):
36
+ id: int
37
+ name: str
38
+
39
+
40
+ async def main() -> None:
41
+ async with AsyncClient(base_url="https://api.example.com") as client:
42
+ user = await client.get("/users/1", response_model=User)
43
+ print(user.name)
44
+ ```
45
+
46
+ ## 📚 [Documentation](https://httpware.readthedocs.io)
47
+
48
+ ## 📦 [PyPI](https://pypi.org/project/httpware)
49
+
50
+ ## 📝 [License](./LICENSE)
51
+
52
+ ## Part of `modern-python`
53
+
54
+ Browse the full list of templates and libraries in [`modern-python`](https://github.com/modern-python) — see the org profile for the categorized index.
@@ -26,7 +26,7 @@ classifiers = [
26
26
  "Topic :: Internet :: WWW/HTTP",
27
27
  "Framework :: AsyncIO",
28
28
  ]
29
- version = "0.1.0"
29
+ version = "0.2.0"
30
30
  dependencies = [
31
31
  "httpx2>=2.0.0,<3.0",
32
32
  "pydantic>=2.0,<3.0",
@@ -38,15 +38,14 @@ otel = [
38
38
  "opentelemetry-api>=1.20",
39
39
  "opentelemetry-sdk>=1.20",
40
40
  ]
41
- niquests = ["niquests>=3.18"]
42
- all = ["httpware[msgspec,otel,niquests]"]
41
+ all = ["httpware[msgspec,otel]"]
43
42
 
44
43
  [project.urls]
45
44
  repository = "https://github.com/modern-python/httpware"
46
45
  docs = "https://httpware.readthedocs.io"
47
46
 
48
47
  [build-system]
49
- requires = ["uv_build>=0.11,<0.12"]
48
+ requires = ["uv_build>=0.11,<1.0"]
50
49
  build-backend = "uv_build"
51
50
 
52
51
  [tool.uv.build-backend]
@@ -74,7 +73,6 @@ fix = true
74
73
  unsafe-fixes = true
75
74
  line-length = 120
76
75
  target-version = "py311"
77
- extend-exclude = ["docs"]
78
76
 
79
77
  [tool.ruff.lint]
80
78
  select = ["ALL"]
@@ -90,24 +88,16 @@ ignore = [
90
88
  ]
91
89
  isort.lines-after-imports = 2
92
90
  isort.no-lines-before = ["standard-library", "local-folder"]
93
- pylint.max-args = 10 # HTTP-method APIs are kwarg-rich (headers, params, cookies, timeout, json, content, response_model, …); default 5 is too strict.
94
91
 
95
92
  [tool.ruff.lint.per-file-ignores]
96
- # AsyncClient's HTTP-method `timeout=` is a config-value parameter forwarded to the transport,
97
- # not asyncio.timeout territory. The rule fires on 24+ method signatures in this one file with
98
- # the same false-positive justification; per-file disable is cleaner than 24 per-line noqa.
99
- "src/httpware/client.py" = ["ASYNC109"]
93
+ "src/httpware/client.py" = ["ASYNC109", "ANN401"]
100
94
 
101
95
  [tool.pytest.ini_options]
102
- addopts = "--cov=src/httpware --cov-report term-missing -m 'not perf'"
96
+ addopts = "--cov=. --cov-report term-missing --cov-fail-under=100"
103
97
  asyncio_mode = "auto"
104
98
  pythonpath = ["src"]
105
99
  asyncio_default_fixture_loop_scope = "function"
106
- markers = [
107
- "perf: assertive performance tests (skipped by default; run with `pytest -m perf`)",
108
- ]
109
100
 
110
101
  [tool.coverage]
111
102
  run.concurrency = ["thread"]
112
- run.omit = ["benchmarks/*"]
113
103
  report.exclude_also = ["if typing.TYPE_CHECKING:"]
@@ -1,7 +1,6 @@
1
- """httpware — resilience-first async HTTP client framework for Python."""
1
+ """httpware — thin async HTTP client wrapper over httpx2."""
2
2
 
3
3
  from httpware.client import AsyncClient
4
- from httpware.config import ClientConfig, Limits, Timeout
5
4
  from httpware.decoders import ResponseDecoder
6
5
  from httpware.decoders.pydantic import PydanticDecoder
7
6
  from httpware.errors import (
@@ -23,41 +22,27 @@ from httpware.errors import (
23
22
  UnprocessableEntityError,
24
23
  )
25
24
  from httpware.middleware import Middleware, Next, after_response, before_request, on_error
26
- from httpware.request import Request
27
- from httpware.response import Response, StreamResponse
28
- from httpware.transports import Transport
29
- from httpware.transports.httpx2 import Httpx2Transport
30
- from httpware.transports.recorded import RecordedTransport
31
25
 
32
26
 
33
27
  __all__ = [
34
28
  "STATUS_TO_EXCEPTION",
35
29
  "AsyncClient",
36
30
  "BadRequestError",
37
- "ClientConfig",
38
31
  "ClientError",
39
32
  "ClientStatusError",
40
33
  "ConflictError",
41
34
  "ForbiddenError",
42
- "Httpx2Transport",
43
35
  "InternalServerError",
44
- "Limits",
45
36
  "Middleware",
46
37
  "Next",
47
38
  "NotFoundError",
48
39
  "PydanticDecoder",
49
40
  "RateLimitedError",
50
- "RecordedTransport",
51
- "Request",
52
- "Response",
53
41
  "ResponseDecoder",
54
42
  "ServerStatusError",
55
43
  "ServiceUnavailableError",
56
44
  "StatusError",
57
- "StreamResponse",
58
- "Timeout",
59
45
  "TimeoutError",
60
- "Transport",
61
46
  "TransportError",
62
47
  "UnauthorizedError",
63
48
  "UnprocessableEntityError",