FastAPI 和 SlowAPI 限制所有“path/*”下的请求
FastAPI and SlowAPI limit request under all “path/*”
我在使用 SlowAPI 时遇到问题。所有的请求都是按照中间件来限制的,但是我没办法把所有的请求都限制在/schools/
这个路径下
我的代码:
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
当我使用 jQuery 向 /schools/{region}/{province}/{city}
发送请求时,整个 url 受到限制,因此如果我更改地区或省份,限制将被重置。如何让自己应用 /schools/*
的设置
示例:
每 5 秒请求 2 次
如果我向 apiURL+/schools/Lombardy/Milan/Milan
发送请求,限制会增加 1,如果我在第三次发出另一个 2 请求,我会被阻止。
但是如果我没有进入同一个域,而是更改了城市 (apiURL+/schools/Sicily/Palermo/Palermo
),限制将重置并且 returns 为 1
选项 1
实例化Limiter
class时定义application_limits
,如下图。根据 documentation、
application_limits:
a variable list of strings or callables returning strings for limits
that are applied to the entire application (i.e., a shared limit for all
routes)
因此,以下将对所有 /schools/*
路由以及您的应用程序中可能存在的任何其他路由(例如 /testpath/*
、/some-other-route/
、依此类推),这意味着每个客户端每 5 秒只能通过两个请求(无论他们调用的端点如何)。
limiter = Limiter(key_func=get_remote_address, application_limits=["2/5seconds"])
选项 2
使用 shared_limit
仅将共享限制应用于您希望的端点。根据 documentation:
shared_limit: Decorator to be applied to multiple routes sharing the same rate limit.
因此,以下将仅对 /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}
我在使用 SlowAPI 时遇到问题。所有的请求都是按照中间件来限制的,但是我没办法把所有的请求都限制在/schools/
我的代码:
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
当我使用 jQuery 向 /schools/{region}/{province}/{city}
发送请求时,整个 url 受到限制,因此如果我更改地区或省份,限制将被重置。如何让自己应用 /schools/*
示例:
每 5 秒请求 2 次
如果我向 apiURL+/schools/Lombardy/Milan/Milan
发送请求,限制会增加 1,如果我在第三次发出另一个 2 请求,我会被阻止。
但是如果我没有进入同一个域,而是更改了城市 (apiURL+/schools/Sicily/Palermo/Palermo
),限制将重置并且 returns 为 1
选项 1
实例化Limiter
class时定义application_limits
,如下图。根据 documentation、
application_limits: a variable list of strings or callables returning strings for limits that are applied to the entire application (i.e., a shared limit for all routes)
因此,以下将对所有 /schools/*
路由以及您的应用程序中可能存在的任何其他路由(例如 /testpath/*
、/some-other-route/
、依此类推),这意味着每个客户端每 5 秒只能通过两个请求(无论他们调用的端点如何)。
limiter = Limiter(key_func=get_remote_address, application_limits=["2/5seconds"])
选项 2
使用 shared_limit
仅将共享限制应用于您希望的端点。根据 documentation:
shared_limit: Decorator to be applied to multiple routes sharing the same rate limit.
因此,以下将仅对 /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}