From 42395aaf5355157ff3c44775d3fa3bcc2e3ff8f9 Mon Sep 17 00:00:00 2001 From: florimondmanca Date: Wed, 5 Aug 2020 23:17:28 +0200 Subject: [PATCH 1/2] Middleware API --- httpx/__init__.py | 3 +++ httpx/_client.py | 29 +++++++++++++++++++++++++---- httpx/_middleware.py | 16 ++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 httpx/_middleware.py diff --git a/httpx/__init__.py b/httpx/__init__.py index 25c70e4bad..273ef6b24f 100644 --- a/httpx/__init__.py +++ b/httpx/__init__.py @@ -32,6 +32,7 @@ WriteError, WriteTimeout, ) +from ._middleware import AsyncMiddleware, Middleware from ._models import URL, Cookies, Headers, QueryParams, Request, Response from ._status_codes import StatusCode, codes from ._transports.asgi import ASGITransport @@ -55,6 +56,8 @@ "codes", "ASGITransport", "AsyncClient", + "AsyncMiddleware", + "Middleware", "Auth", "BasicAuth", "Client", diff --git a/httpx/_client.py b/httpx/_client.py index e4b212b4ac..17821c9708 100644 --- a/httpx/_client.py +++ b/httpx/_client.py @@ -25,6 +25,7 @@ TooManyRedirects, map_exceptions, ) +from ._middleware import Middleware, AsyncMiddleware from ._models import URL, Cookies, Headers, QueryParams, Request, Response from ._status_codes import codes from ._transports.asgi import ASGITransport @@ -452,6 +453,7 @@ def __init__( max_redirects: int = DEFAULT_MAX_REDIRECTS, base_url: URLTypes = None, transport: httpcore.SyncHTTPTransport = None, + middleware: typing.Sequence[Middleware] = (), app: typing.Callable = None, trust_env: bool = True, ): @@ -502,6 +504,8 @@ def __init__( } self._proxies = dict(sorted(self._proxies.items())) + self._middleware = middleware + def _init_transport( self, verify: VerifyTypes = True, @@ -610,9 +614,16 @@ def send( auth = self._build_auth(request, auth) - response = self._send_handling_redirects( - request, auth=auth, timeout=timeout, allow_redirects=allow_redirects, + call_next = functools.partial( + self._send_handling_redirects, + auth=auth, + allow_redirects=allow_redirects, + timeout=timeout, ) + for middleware in self._middleware: + call_next = functools.partial(middleware.send, call_next=call_next) + + response = call_next(request) if not stream: try: @@ -983,6 +994,7 @@ def __init__( max_redirects: int = DEFAULT_MAX_REDIRECTS, base_url: URLTypes = None, transport: httpcore.AsyncHTTPTransport = None, + middleware: typing.Sequence[AsyncMiddleware] = (), app: typing.Callable = None, trust_env: bool = True, ): @@ -1033,6 +1045,8 @@ def __init__( } self._proxies = dict(sorted(self._proxies.items())) + self._middleware = middleware + def _init_transport( self, verify: VerifyTypes = True, @@ -1138,9 +1152,16 @@ async def send( auth = self._build_auth(request, auth) - response = await self._send_handling_redirects( - request, auth=auth, timeout=timeout, allow_redirects=allow_redirects, + call_next = functools.partial( + self._send_handling_redirects, + auth=auth, + allow_redirects=allow_redirects, + timeout=timeout, ) + for middleware in self._middleware: + call_next = functools.partial(middleware.asend, call_next=call_next) + + response = await call_next(request) if not stream: try: diff --git a/httpx/_middleware.py b/httpx/_middleware.py new file mode 100644 index 0000000000..79aa1e7765 --- /dev/null +++ b/httpx/_middleware.py @@ -0,0 +1,16 @@ +from typing import Callable, Awaitable +from ._models import Request, Response + + +class Middleware: + def send( + self, request: Request, call_next: Callable[[Request], Response] + ) -> Response: + raise NotImplementedError # pragma: no cover + + +class AsyncMiddleware: + async def asend( + self, request: Request, call_next: Callable[[Request], Awaitable[Response]] + ) -> Response: + raise NotImplementedError # pragma: no cover From 3006f3fc6290e73f80a6508c2671883ea7aad9b9 Mon Sep 17 00:00:00 2001 From: florimondmanca Date: Wed, 5 Aug 2020 23:46:09 +0200 Subject: [PATCH 2/2] Lint --- httpx/_client.py | 2 +- httpx/_middleware.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/httpx/_client.py b/httpx/_client.py index 17821c9708..0ec01e376a 100644 --- a/httpx/_client.py +++ b/httpx/_client.py @@ -25,7 +25,7 @@ TooManyRedirects, map_exceptions, ) -from ._middleware import Middleware, AsyncMiddleware +from ._middleware import AsyncMiddleware, Middleware from ._models import URL, Cookies, Headers, QueryParams, Request, Response from ._status_codes import codes from ._transports.asgi import ASGITransport diff --git a/httpx/_middleware.py b/httpx/_middleware.py index 79aa1e7765..61890332c6 100644 --- a/httpx/_middleware.py +++ b/httpx/_middleware.py @@ -1,4 +1,5 @@ -from typing import Callable, Awaitable +from typing import Awaitable, Callable + from ._models import Request, Response