- PostgreSQL schema: 14 tables, JSONB attributes, audit triggers, soft delete - FastAPI backend: CRUD, search/filter, relationship graph, bulk import, JWT RBAC - React frontend: CI table, detail card, force-graph, dashboard - Seed data: homelab scenario (Proxmox, Mikrotik, VMs, services) - Docker Compose + Kubernetes manifests - 20 backend tests (pytest + httpx)
24 lines
706 B
Python
24 lines
706 B
Python
import time
|
|
from collections import defaultdict
|
|
from fastapi import Request, HTTPException
|
|
from app.config import get_settings
|
|
|
|
settings = get_settings()
|
|
|
|
_requests: dict[str, list[float]] = defaultdict(list)
|
|
|
|
|
|
async def rate_limit_middleware(request: Request, call_next):
|
|
client_ip = request.client.host if request.client else "unknown"
|
|
now = time.time()
|
|
window = 60.0
|
|
|
|
_requests[client_ip] = [t for t in _requests[client_ip] if now - t < window]
|
|
|
|
if len(_requests[client_ip]) >= settings.RATE_LIMIT_PER_MINUTE:
|
|
raise HTTPException(status_code=429, detail="Rate limit exceeded")
|
|
|
|
_requests[client_ip].append(now)
|
|
response = await call_next(request)
|
|
return response
|