Files
romm/backend/utils/context.py
T
Georges-Antoine Assi 4a8c3423df run trunk fmt
2026-04-02 10:21:43 -04:00

63 lines
1.9 KiB
Python

from collections.abc import AsyncGenerator, Awaitable, Callable
from contextlib import asynccontextmanager
from contextvars import ContextVar, Token
from typing import TypeVar
import aiohttp
import httpx
from fastapi import Request, Response
from config import has_proxy_env
_T = TypeVar("_T")
ctx_aiohttp_session: ContextVar[aiohttp.ClientSession] = ContextVar("aiohttp_session")
ctx_httpx_client: ContextVar[httpx.AsyncClient] = ContextVar("httpx_client")
def create_aiohttp_session() -> aiohttp.ClientSession:
return aiohttp.ClientSession(trust_env=has_proxy_env())
def create_httpx_async_client() -> httpx.AsyncClient:
return httpx.AsyncClient(trust_env=has_proxy_env())
def create_httpx_client() -> httpx.Client:
return httpx.Client(trust_env=has_proxy_env())
@asynccontextmanager
async def set_context_var(var: ContextVar[_T], value: _T) -> AsyncGenerator[Token[_T]]:
"""Temporarily set a context variables."""
token = var.set(value)
yield token
var.reset(token)
@asynccontextmanager
async def initialize_context() -> AsyncGenerator[None]:
"""Initialize context variables."""
async with (
create_aiohttp_session() as aiohttp_session,
create_httpx_async_client() as httpx_client,
set_context_var(ctx_aiohttp_session, aiohttp_session),
set_context_var(ctx_httpx_client, httpx_client),
):
yield
async def set_context_middleware(
request: Request, call_next: Callable[[Request], Awaitable[Response]]
) -> Response:
"""Initialize context variables in FastAPI request-response cycle.
This middleware is needed because the context initialized during the lifespan
process is not available in the request-response cycle.
"""
async with (
set_context_var(ctx_aiohttp_session, request.app.state.aiohttp_session),
set_context_var(ctx_httpx_client, request.app.state.httpx_client),
):
return await call_next(request)