Skip to content

feat(story-1.4): transport protocol and Httpx2Transport adapter#4

Merged
lesnik512 merged 1 commit into
mainfrom
story/1-4-transport-protocol-and-httpx2transport-adapter
May 14, 2026
Merged

feat(story-1.4): transport protocol and Httpx2Transport adapter#4
lesnik512 merged 1 commit into
mainfrom
story/1-4-transport-protocol-and-httpx2transport-adapter

Conversation

@lesnik512
Copy link
Copy Markdown
Member

Adds the Transport protocol (Seam 1, middleware ↔ transport) and the default Httpx2Transport implementation — the single seam where httpx2 is imported. Adds a minimal StreamResponse placeholder so the protocol's stream() signature can be typed today and fleshed out in Story 4.1.

  • src/httpware/transports/init.py: @runtime_checkable Transport Protocol with call / stream / aclose
  • src/httpware/transports/httpx2.py: Httpx2Transport adapter; lazy AsyncClient init guarded by asyncio.Lock; httpx2.{TimeoutException, HTTPError, InvalidURL, CookieConflict} and the closed-client RuntimeError mapped to httpware.{TimeoutError, TransportError} with the original message preserved on the mapped instance
  • src/httpware/response.py: StreamResponse placeholder (status, headers, url) re-exported from httpware/init.py
  • tests/test_no_httpx2_leakage.py: CI invariant — only transports/httpx2.py may import httpx2; cwd-robust pathing
  • tests/test_transports_httpx2.py: 63 unit tests covering protocol membership, success / 4xx / 5xx / exception-mapping / lazy-init / concurrent-init / post-close paths
  • docs/stories/1-4-...: story spec + Review Findings with 3-layer adversarial review outcome
  • docs/deferred-work.md: 5 review-time deferrals + extended case-insensitive-headers entry to cover multi-value collapse
  • CHANGELOG.md: Unreleased / Added entry

Full suite 140 passing, 100% coverage on every source module, lint green (ruff + ty), httpx2 leakage invariant holds.

Adds the Transport protocol (Seam 1, middleware ↔ transport) and the
default Httpx2Transport implementation — the single seam where httpx2 is
imported. Adds a minimal StreamResponse placeholder so the protocol's
stream() signature can be typed today and fleshed out in Story 4.1.

- src/httpware/transports/__init__.py: @runtime_checkable Transport
  Protocol with __call__ / stream / aclose
- src/httpware/transports/httpx2.py: Httpx2Transport adapter; lazy
  AsyncClient init guarded by asyncio.Lock; httpx2.{TimeoutException,
  HTTPError, InvalidURL, CookieConflict} and the closed-client
  RuntimeError mapped to httpware.{TimeoutError, TransportError} with
  the original message preserved on the mapped instance
- src/httpware/response.py: StreamResponse placeholder (status, headers,
  url) re-exported from httpware/__init__.py
- tests/test_no_httpx2_leakage.py: CI invariant — only
  transports/httpx2.py may import httpx2; cwd-robust pathing
- tests/test_transports_httpx2.py: 63 unit tests covering protocol
  membership, success / 4xx / 5xx / exception-mapping / lazy-init /
  concurrent-init / post-close paths
- docs/stories/1-4-...: story spec + Review Findings with 3-layer
  adversarial review outcome
- docs/deferred-work.md: 5 review-time deferrals + extended
  case-insensitive-headers entry to cover multi-value collapse
- CHANGELOG.md: Unreleased / Added entry

Full suite 140 passing, 100% coverage on every source module, lint
green (ruff + ty), httpx2 leakage invariant holds.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@lesnik512 lesnik512 self-assigned this May 14, 2026
@lesnik512 lesnik512 merged commit 4d92460 into main May 14, 2026
5 checks passed
@lesnik512 lesnik512 deleted the story/1-4-transport-protocol-and-httpx2transport-adapter branch May 14, 2026 05:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant