structured-data-extractor / src /api /middleware.py
aditya0103's picture
Tasks 5-7: eval harness, FastAPI backend, Paper & Ink UI- src/eval/ β€” precision/recall/F1 harness with type-aware comparators,micro/macro F1, CSV + markdown reports, --model benchmark flag- src/api/ β€” FastAPI backend with /extract, /schemas, /health,request-ID middleware, typed error envelope, injectable extractor- ui/ β€” Vite + React + TS + Tailwind + Motion + React Three FiberPaper & Ink editorial UI with 3D paper hero, dark/light mode,confidence inkwell, wax-stamp metrics, kinetic typography- 95 passing tests (up from 54); UI is a separate npm workspace
557ab38
Raw
History Blame Contribute Delete
1.67 kB
"""Middleware: request IDs + structured access logs.
RequestIDMiddleware attaches a UUID4 to every request as `X-Request-ID`. Both
the response header and the log line carry it so a user reporting an error can
give you the ID and you can find the log.
StructuredLoggingMiddleware logs one JSON line per request with method, path,
status, latency, and the request ID.
"""
from __future__ import annotations
import time
import uuid
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import Response
from src.utils.logging import logger
REQUEST_ID_HEADER = "X-Request-ID"
class RequestIDMiddleware(BaseHTTPMiddleware):
"""Assign each request a UUID and echo it in the response header."""
async def dispatch(self, request: Request, call_next):
rid = request.headers.get(REQUEST_ID_HEADER) or str(uuid.uuid4())
request.state.request_id = rid
response: Response = await call_next(request)
response.headers[REQUEST_ID_HEADER] = rid
return response
class AccessLogMiddleware(BaseHTTPMiddleware):
"""One log line per request with method, path, status, latency, request_id."""
async def dispatch(self, request: Request, call_next):
start = time.perf_counter()
response: Response = await call_next(request)
latency_ms = (time.perf_counter() - start) * 1000
rid = getattr(request.state, "request_id", "-")
logger.info(
f"[api] method={request.method} path={request.url.path} "
f"status={response.status_code} latency_ms={latency_ms:.1f} rid={rid}"
)
return response