""" Lightweight in-process rate limiting helpers. """ from __future__ import annotations import threading import time from collections import defaultdict, deque from fastapi import HTTPException, Request, status _lock = threading.Lock() _hits: dict[str, deque[float]] = defaultdict(deque) def _client_ip(request: Request) -> str: if request.client and request.client.host: return request.client.host return "unknown" def enforce_rate_limit( request: Request, *, scope: str, max_requests: int, window_seconds: int, ) -> None: now = time.time() ip = _client_ip(request) key = f"{scope}:{ip}" cutoff = now - window_seconds with _lock: dq = _hits[key] while dq and dq[0] <= cutoff: dq.popleft() if len(dq) >= max_requests: raise HTTPException( status_code=status.HTTP_429_TOO_MANY_REQUESTS, detail=f"Too many requests for {scope}. Please try again later.", ) dq.append(now)