Using the httpx client#
Safir helps you manage a single
httpx.AsyncClient for your application.
Using a single HTTP client improves performance by reusing connections.
Setting up the httpx.AsyncClient#
httpx.AsyncClient will be dyanmically created during application startup.
Nothing further is needed apart from importing the dependency.
However, it must be closed during application shutdown or a warning will be generated.
To do this, add a shutdown hook to your application:
from safir.dependencies.http_client import http_client_dependency app = FastAPI() @app.on_event("shutdown") async def shutdown_event() -> None: await http_client_dependency.aclose()
You can add this line to an existing shutdown hook if you already have one.
Using the httpx.AsyncClient#
To use the client in a handler, just request it via a FastAPI dependency:
from safir.dependencies.http_client import http_client_dependency @routes.get("/") async def get_index( http_client: httpx.AsyncClient = Depends(http_client_dependency), ) -> Dict[str, Any]: response = await http_client.get("https://keeper.lsst.codes") return await response.json()
If you are using
httpx.AsyncClient in your application tests as well, note that it will not trigger shutdown events, so if you trigger handlers that use the HTTP client, you will get a warning about an unclosed
httpx.AsyncClient in your test output.
To avoid this, wrap your test application in
asgi_lifespan.LifespanManager from the asgi-lifespan Python package:
app = FastAPI() async with LifespanManager(app): # insert tests here pass
You can do this in a fixture to avoid code duplication.