"""HTTP middleware helpers (Flask request hooks).""" from __future__ import annotations import logging import time from flask import Flask, g, request from . import settings from .metrics import observe_request from .utils import generate_request_id def register_request_hooks(app: Flask) -> None: """Attach before/after request handlers for logging and correlation.""" @app.before_request def attach_request_id_and_log(): # type: ignore[unused-ignore] rid = request.headers.get("X-Request-Id") if not rid: rid = generate_request_id() request.environ["HTTP_X_REQUEST_ID"] = rid request.request_id = rid # type: ignore[attr-defined] if settings.ENABLE_REQUEST_LOGS: try: logging.info( "request.start", extra={ "request_id": rid, "method": request.method, "path": request.path, "remote_addr": request.remote_addr, }, ) except Exception: pass try: g._start_time = time.time() except Exception: g._start_time = None # type: ignore[attr-defined] @app.after_request def add_request_id_header(response): # type: ignore[unused-ignore] try: rid = getattr(request, "request_id", None) or request.environ.get("HTTP_X_REQUEST_ID") if rid: response.headers["X-Request-Id"] = rid if settings.ENABLE_REQUEST_LOGS: try: logging.info( "request.end", extra={ "request_id": rid, "status": response.status_code, "path": request.path, }, ) except Exception: pass start_time = getattr(g, "_start_time", None) observe_request(request.method, request.path, start_time, response.status_code) except Exception: pass return response