Advanced Usage
Authenticate a Request¶
Use the AuthMiddleware to provide required authentication to the outgoing request.
Httperactor has a concept of a SubRequest, which represents a request type used by the module that connects to the HTTP server. Httperactor uses the httpx package as the default HTTP client, so the SubRequest becomes the httpx.Request.
Following example defines an AuthMiddleware that adds an Authorization header to the httpx.Request:
import httpx
import httperactor
class BearerTokenAuthMiddleware(httperactor.AuthMiddleware[httpx.Request]):
def __init__(self, token: str):
self._token: str = token
def apply(self, request: httpx.Request) -> httpx.Request:
request.headers["Authorization"] = f"Bearer {self._token}"
return request
To have the interactor use the middleware, override the auth property:
import httpx
import httperactor
...
class GetBooksInteractor(httperactor.HttpInteractor[httpx.Request, Sequence[Book], State]):
@property
def request(self) -> httperactor.Request[Sequence[Book]]:
return GetBooksRequest()
@property
def auth(self) -> httperactor.AuthMiddleware[httpx.Request] | None:
return BearerTokenAuthMiddleware(token="MY_SECRET_TOKEN")
Use a custom HttpClient¶
Httperactor ships with a HttpClient that uses the httpx package for sending the HTTP requests.
You can provide your own client by subclassing the HttpClientBase.
Following example defines a simple client using the tornado package:
from typing import TypeVar
import tornado.httpclient as tornado
from httperactor import AuthMiddleware, HttpClientBase, Request
TResponse = TypeVar("TResponse")
class TornadoHttpClient(HttpClientBase[tornado.HTTPRequest]):
async def send(
self,
request: Request[TResponse],
auth: AuthMiddleware[tornado.HTTPRequest] | None = None,
) -> TResponse | None:
tornado_request = tornado.HTTPRequest(
url=f"http://localhost:5000{request.path}",
method=request.method,
)
http_client = tornado.AsyncHTTPClient()
response = await http_client.fetch(tornado_request)
return request.map_response(response.body.decode())