Skip to content

ccproxy.api.middleware.request_id

ccproxy.api.middleware.request_id

Request ID middleware for generating and tracking request IDs.

RequestIDMiddleware

RequestIDMiddleware(app)

Bases: BaseHTTPMiddleware

Middleware for generating request IDs and initializing request context.

Parameters:

Name Type Description Default
app ASGIApp

The ASGI application

required
Source code in ccproxy/api/middleware/request_id.py
def __init__(self, app: ASGIApp):
    """Initialize the request ID middleware.

    Args:
        app: The ASGI application
    """
    super().__init__(app)

dispatch async

dispatch(request, call_next)

Process the request and add request ID/context.

Parameters:

Name Type Description Default
request Request

The incoming HTTP request

required
call_next Any

The next middleware/handler in the chain

required

Returns:

Type Description
Response

The HTTP response

Source code in ccproxy/api/middleware/request_id.py
async def dispatch(self, request: Request, call_next: Any) -> Response:
    """Process the request and add request ID/context.

    Args:
        request: The incoming HTTP request
        call_next: The next middleware/handler in the chain

    Returns:
        The HTTP response
    """
    # Generate or extract request ID
    request_id = request.headers.get("x-request-id") or str(uuid.uuid4())

    # Get DuckDB storage from app state if available
    storage = getattr(request.app.state, "duckdb_storage", None)

    # Use the proper request context manager to ensure __aexit__ is called
    async with request_context(
        request_id=request_id,
        storage=storage,
        method=request.method,
        path=str(request.url.path),
        client_ip=request.client.host if request.client else "unknown",
        user_agent=request.headers.get("user-agent", "unknown"),
        query=str(request.url.query) if request.url.query else None,
        service_type="access_log",
    ) as ctx:
        # Store context in request state for access by services
        request.state.request_id = request_id
        request.state.context = ctx

        # Add DuckDB storage to context if available
        if hasattr(request.state, "duckdb_storage"):
            ctx.storage = request.state.duckdb_storage

        # Process the request
        response = await call_next(request)

        # Add request ID to response headers
        response.headers["x-request-id"] = request_id

        return response  # type: ignore[no-any-return]