from fastapi import FastAPI, Request, HTTPException
import time
app = FastAPI()
buckets = {} # {ip: (tokens, last_ts)}
RATE = 5 # токенов/сек
BURST = 20 # максимум в бакете
def allow(ip):
now = time.time()
tokens, ts = buckets.get(ip, (BURST, now))
tokens = min(BURST, tokens + (now - ts) * RATE)
if tokens < 1:
buckets[ip] = (tokens, now)
return False
buckets[ip] = (tokens - 1, now)
return True
@app.middleware("http")
async def rate_limiter(request: Request, call_next):
ip = request.client.host
if not allow(ip):
raise HTTPException(status_code=429, detail="Too many requests")
return await call_next(request)