Rate Limiting en FastAPI: protege tus endpoints con slowapi paso a paso

Tiempo de lectura: < 1 minuto

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

Puerta - pexels

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)))

Deja un comentario