""" Rate limiting middleware that limits requests per IP address """
import time
from collections import defaultdict, deque
from fastapi.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware
class RateLimitMiddleware(BaseHTTPMiddleware):
def __init__(self, app, requests_per_minute: int = 60):
super().__init__(app)
self.requests_per_minute = requests_per_minute
self.request_history = defaultdict(lambda: deque())
async def dispatch(self, request: Request, call_next):
client_ip = request.client.host if request.client else "unknown"
current_time = time.time()
# Clean old requests
history = self.request_history[client_ip]
while history and current_time - history[0] > 60:
history.popleft()
# Check rate limit
if len(history) >= self.requests_per_minute:
return JSONResponse(
status_code=429,
content={"detail": "Rate limit exceeded"}
)
history.append(current_time)
return await call_next(request)