"""Request correlation middleware (``API-STANDARD.md`` ยง7).""" from __future__ import annotations import uuid from collections.abc import Callable from django.http import HttpRequest, HttpResponse __all__ = ["RequestIdMiddleware", "RateLimitHeadersMiddleware"] _HEADER = "X-Request-Id" class RequestIdMiddleware: """Ensures every request has an id, echoed in the response header and meta.""" def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]) -> None: self.get_response = get_response def __call__(self, request: HttpRequest) -> HttpResponse: request_id = request.headers.get(_HEADER) or f"req_{uuid.uuid4().hex[:20]}" request.request_id = request_id # type: ignore[attr-defined] response = self.get_response(request) response[_HEADER] = request_id return response class RateLimitHeadersMiddleware: """Adds ``X-RateLimit-*`` headers whenever a throttle recorded state.""" def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]) -> None: self.get_response = get_response def __call__(self, request: HttpRequest) -> HttpResponse: from .throttling import apply_rate_limit_headers response = self.get_response(request) apply_rate_limit_headers(response, request) return response