httpware 0.8.4__tar.gz → 0.8.6__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.
Files changed (22) hide show
  1. {httpware-0.8.4 → httpware-0.8.6}/PKG-INFO +1 -1
  2. {httpware-0.8.4 → httpware-0.8.6}/pyproject.toml +1 -1
  3. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/decoders/pydantic.py +8 -7
  4. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/middleware/chain.py +5 -7
  5. {httpware-0.8.4 → httpware-0.8.6}/README.md +0 -0
  6. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/__init__.py +0 -0
  7. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/_internal/__init__.py +0 -0
  8. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/_internal/exception_mapping.py +0 -0
  9. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/_internal/import_checker.py +0 -0
  10. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/_internal/observability.py +0 -0
  11. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/_internal/status.py +0 -0
  12. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/client.py +0 -0
  13. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/decoders/__init__.py +0 -0
  14. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/decoders/msgspec.py +0 -0
  15. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/errors.py +0 -0
  16. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/middleware/__init__.py +0 -0
  17. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/middleware/resilience/__init__.py +0 -0
  18. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/middleware/resilience/_backoff.py +0 -0
  19. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/middleware/resilience/budget.py +0 -0
  20. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/middleware/resilience/bulkhead.py +0 -0
  21. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/middleware/resilience/retry.py +0 -0
  22. {httpware-0.8.4 → httpware-0.8.6}/src/httpware/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: httpware
3
- Version: 0.8.4
3
+ Version: 0.8.6
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
@@ -26,7 +26,7 @@ classifiers = [
26
26
  "Topic :: Internet :: WWW/HTTP",
27
27
  "Framework :: AsyncIO",
28
28
  ]
29
- version = "0.8.4"
29
+ version = "0.8.6"
30
30
  dependencies = [
31
31
  "httpx2>=2.0.0,<3.0",
32
32
  ]
@@ -1,19 +1,20 @@
1
1
  """PydanticDecoder — module-level cached TypeAdapter adapter for ResponseDecoder.
2
2
 
3
- Requires the `pydantic` extra: `pip install httpware[pydantic]`. Importing this
4
- module without the extra works (the `pydantic` import is guarded by a
5
- `find_spec` check), but instantiating the decoder raises `ImportError` with the
3
+ Requires the `pydantic` extra: `pip install httpware[pydantic]`. The optional-extras
4
+ gate is enforced upstream `client.py:_default_pydantic_decoder()` raises
5
+ ImportError when pydantic is absent, so this module is never imported in that
6
+ path. Tests simulating "pydantic not installed" patch
7
+ `import_checker.is_pydantic_installed=False` at runtime, after this module is
8
+ already loaded; `PydanticDecoder.__init__` then raises ImportError with the
6
9
  install hint.
7
10
  """
8
11
 
9
12
  import functools
10
13
  from typing import TypeVar
11
14
 
12
- from httpware._internal import import_checker
13
-
15
+ from pydantic import TypeAdapter
14
16
 
15
- if import_checker.is_pydantic_installed:
16
- from pydantic import TypeAdapter
17
+ from httpware._internal import import_checker
17
18
 
18
19
 
19
20
  MISSING_DEPENDENCY_MESSAGE = (
@@ -5,16 +5,14 @@ from collections.abc import Awaitable, Callable, Sequence
5
5
 
6
6
  import httpx2
7
7
 
8
-
9
- if typing.TYPE_CHECKING:
10
- from httpware.middleware import AsyncMiddleware, Middleware
8
+ from httpware.middleware import AsyncMiddleware, Middleware
11
9
 
12
10
 
13
11
  _AsyncNext: typing.TypeAlias = Callable[[httpx2.Request], Awaitable[httpx2.Response]]
14
12
  _Next: typing.TypeAlias = Callable[[httpx2.Request], httpx2.Response]
15
13
 
16
14
 
17
- def compose_async(middleware: "Sequence[AsyncMiddleware]", terminal: _AsyncNext) -> _AsyncNext:
15
+ def compose_async(middleware: Sequence[AsyncMiddleware], terminal: _AsyncNext) -> _AsyncNext:
18
16
  """Fold `middleware` into a single callable around `terminal`.
19
17
 
20
18
  The first middleware in the sequence is the outermost wrapper.
@@ -25,14 +23,14 @@ def compose_async(middleware: "Sequence[AsyncMiddleware]", terminal: _AsyncNext)
25
23
  return dispatch
26
24
 
27
25
 
28
- def _wrap(layer: "AsyncMiddleware", inner: _AsyncNext) -> _AsyncNext:
26
+ def _wrap(layer: AsyncMiddleware, inner: _AsyncNext) -> _AsyncNext:
29
27
  async def call(request: httpx2.Request) -> httpx2.Response:
30
28
  return await layer(request, inner)
31
29
 
32
30
  return call
33
31
 
34
32
 
35
- def compose(middleware: "Sequence[Middleware]", terminal: _Next) -> _Next:
33
+ def compose(middleware: Sequence[Middleware], terminal: _Next) -> _Next:
36
34
  """Fold sync `middleware` into a single callable around sync `terminal`.
37
35
 
38
36
  The first middleware in the sequence is the outermost wrapper.
@@ -43,7 +41,7 @@ def compose(middleware: "Sequence[Middleware]", terminal: _Next) -> _Next:
43
41
  return dispatch
44
42
 
45
43
 
46
- def _wrap_sync(layer: "Middleware", inner: _Next) -> _Next:
44
+ def _wrap_sync(layer: Middleware, inner: _Next) -> _Next:
47
45
  def call(request: httpx2.Request) -> httpx2.Response:
48
46
  return layer(request, inner)
49
47
 
File without changes
File without changes