I'm trying to migrate a FastAPI pattern to Litestar.
The original one is something like:
from contextvars import ContextVar
from typing import Annotated, Any
from fastapi import Depends, FastAPI, Header, Request
from pydantic import Field
logging_context: ContextVar[dict[str, Any] | None] = ContextVar("logging_context", default=None)
async def update_context(
request: Request,
correlation_id: Annotated[str, Field(pattern=r"...")] = Header(),
) -> None:
context = {"correlation_id": correlation_id}
if token := request.state.get("jwt_token", None):
context["user"] = token.user
logging_context.set(context)
app = FastAPI(dependencies=[Depends(update_context)])
For the uncorrupted, this would allow the dependency to be called before every endpoint, which adds some information to a global contextvar that would later be used for logging. "Authors of Business Logic" don't have to do any configuration themselves to enjoy coherent logging.
Moving this into Litestar, I realized there isn't a way to use the dependency without calling it explicitly. I managed to get what I want with before_request, but is this the best way to do it?
async def before_request_app(request: Request) -> None:
context = {}
if (correlation_id := request.headers.get("correlation-id")) and re.match(r"...", correlation_id):
context["correlation_id"] = correlation_id
if token := request.state.get("token", None):
context["user"] = token.user
logging_context.set(context)
app = Litestar(
route_handlers=[index],
logging_config=logging_config(),
before_request=before_request_app,
)
Or is there another way to achieve this, preferrably without using structlog?
My "reservations" with this is just that it isn't foolproof, if another author uses a before_request in an inner layer, it will get overridden.
Thanks in advance for your time