Tengo un problema con SlowAPI. Todas las solicitudes están limitadas de acuerdo con el middleware, pero no puedo limitar de forma conjunta todas las solicitudes en la ruta /schools/
Mi código:
from fastapi import FastAPI, Request, Response, status from fastapi.middleware.cors import CORSMiddleware from slowapi import Limiter, _rate_limit_exceeded_handler from slowapi.util import get_remote_address from slowapi.errors import RateLimitExceeded from slowapi.middleware import SlowAPIMiddleware limiter = Limiter(key_func=get_remote_address, default_limits=["2/5seconds"]) app = FastAPI() app.state.limiter = limiter app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler) origins = ["http://127.0.0.1/", "http://localhost", "http://192.168.1.75"] ## CORS app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.add_middleware(SlowAPIMiddleware) ## Rate-limit all request @app.get('/schools/{regione}/{provincia}/{comune}') def search_school(request: Request, response: Response, regione: str, provincia: str, comune: str): return {"message": 'No schools found!', "status": 'error', "code": 200} ## Or if found return schools informations @app.get('/testpath/{regione}') ## Works with one path. If I add "provincia" and "comune" non work def search_school(request: Request, response: Response, regione: str, provincia: str, comune: str): return {"message": 'No schools found!', "status": 'error', "code": 200} ## Or if found return schools informations Cuando envío una solicitud a /schools/{region}/{province}/{city} con jQuery, toda la URL está limitada y, por lo tanto, si cambio de región o provincia, los límites se restablecen. ¿Cómo puedo aplicar la configuración para /schools/* ?
Ejemplo:
2 solicitudes cada 5 segundos
Si envío una solicitud a apiURL+/schools/Lombardy/Milan/Milan el límite aumenta en 1 y si realizo otras 2 solicitudes en la tercera, me bloquean.
Pero si en lugar de hacerlo en el mismo dominio, cambio la ciudad ( apiURL+/schools/Sicily/Palermo/Palermo ), el límite se restablece y vuelve a 1
Defina application_limits al instanciar la clase Limiter , como se muestra a continuación. Según la documentación ,
application_limits : una lista variable de cadenas o invocables que devuelven cadenas para límites que se aplican a toda la aplicación (es decir, un límite compartido para todas las rutas)
Por lo tanto, lo siguiente aplicaría un límite compartido a todas las rutas /schools/* , así como a cualquier otra ruta que pueda estar en su aplicación (p. ej., /testpath/* , /some-other-route/ , etc.), lo que significa que cada cliente solo procesaría dos solicitudes cada 5 segundos (independientemente del punto final al que llamarían).
limiter = Limiter(key_func=get_remote_address, application_limits=["2/5seconds"]) Aplique un límite compartido solo a los puntos finales que desee, usando shared_limit . Según la documentación :
shared_limit : Decorador que se aplicará a varias rutas que compartan el mismo límite de velocidad.
Por lo tanto, lo siguiente aplicaría un límite compartido solo a las rutas /schools/* .
limiter = Limiter(key_func=get_remote_address, default_limits=["2/5seconds"]) @app.get('/schools/{regione}/{provincia}/{comune}') @limiter.shared_limit(limit_value="2/5seconds", scope="schools") def search_school(request: Request, response: Response, regione: str, provincia: str, comune: str): return {"message": 'No schools found!', "status": 'error', "code": 200}