Podemos implementar Rate Limit para nuestras llamadas usando slowapi, que es el equivalente de Flask-Limiter pero para FastAPI:

bash
pip install slowapi
python
# main.py from slowapi import Limiter, _rate_limit_exceeded_handler from slowapi.util import get_remote_address from slowapi.errors import RateLimitExceeded limiter = Limiter(key_func=get_remote_address) app.state.limiter = limiter app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
python
# app/routers/users.py
from slowapi import Limiter
from slowapi.util import get_remote_address
limiter = Limiter(key_func=get_remote_address)
@router.get("/register")
@limiter.limit("5/5seconds")
async def register(request: Request, ...):
...
@router.get("/nuestro_endpoint")
@limiter.limit("5/5seconds")
async def nuestro_endpoint(request: Request, ...):
...
Por defecto usa memoria, pero como ya tienes Redis:
python
limiter = Limiter(
key_func=get_remote_address,
storage_uri="redis://localhost:6379"
)
Cambia localhost por el nombre de tu contenedor Redis si estás en Docker Compose.
Y con esta configuración no nos pertmirá hacer más de 5 llamadas cada 5 segundos.
Decoradores posibles:
# Por segundo
@limiter.limit("10/second")
@limiter.limit("10/seconds")
# Por minuto
@limiter.limit("10/minute")
@limiter.limit("10/minutes")
# Por hora
@limiter.limit("10/hour")
@limiter.limit("10/hours")
# Por día
@limiter.limit("10/day")
@limiter.limit("10/days")
# Múltiples a la vez (AND, se aplican todos)
@limiter.limit("5/second;100/minute;1000/day")
# Con variable
@limiter.limit("10/minute", key_func=lambda r: r.headers.get("X-API-Key", get_remote_address(r)))

Ingeniero en Informática, Investigador, me encanta crear cosas o arreglarlas y darles una nueva vida. Escritor y poeta. Más de 20 APPs publicadas y un libro en Amazon.