-
Notifications
You must be signed in to change notification settings - Fork 2
Closed
Description
Summary
The handler layer currently uses requests.PreparedRequest as its internal request representation. This ties the core business logic to the requests library unnecessarily, since handlers immediately decompose it into primitive types (str, bytes, Mapping[str, str]) before passing them to validators.
Problem
- The
respxadapter must converthttpx.Request→PreparedRequest, which caused type-checking conflicts between mypy, pyrefly, and ruff (see Add respx support for mocking httpx requests #2973) - The Flask server path already doesn't use
PreparedRequest— it extracts primitives directly from Flask/werkzeug's request object PreparedRequest.bodyisbytes | str | None, requiring a_body_bytes()normalizer in two separate filesPreparedRequest.methodisstr | None, requiringor ""guards in every handler
Proposed Solution
Replace PreparedRequest with a simple, library-agnostic dataclass:
@dataclass(frozen=True)
class MockRequest:
method: str
path: str
headers: Mapping[str, str]
body: bytesEach adapter converts to this at the boundary:
responsesadapter:PreparedRequest→MockRequestrespxadapter:httpx.Request→MockRequest- Flask server:
flask.request→MockRequest
Benefits
- Removes dependency on
requeststypes in the handler/validator layer - Eliminates type-checking workarounds (
# type: ignore,# noqa) in the respx adapter - Removes the duplicated
_body_bytes()helper (body normalization happens once at conversion) - Removes
or ""guards for method (normalization happens once at conversion) - Makes the architecture consistent — all three adapters convert to the same internal type
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels