FastAPI和SlowAPI限制所有“path/*”下的请求

Mat*_*teo 4 python fastapi slowapi

我在使用 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
Run Code Online (Sandbox Code Playgroud)

当我使用 jQuery 发送请求时,/schools/{region}/{province}/{city}整个 url 受到限制,因此如果我更改区域或省份,限制将被重置。我怎样才能让自己应用设置/schools/*

例子:

每 5 秒 2 个请求

如果我发送请求的apiURL+/schools/Lombardy/Milan/Milan限制增加 1,并且如果我在第三次发出另外 2 个请求,我会被阻止。

但是,如果我更改城市 ( apiURL+/schools/Sicily/Palermo/Palermo),而不是使其进入同一域,则限制将重置并返回到 1

Chr*_*ris 5

选项1

application_limits实例化类时定义Limiter,如下所示。根据文档

application_limits:字符串或可调用对象的变量列表,返回应用于整个应用程序的限制字符串(即所有路由的共享限制)

/schools/*因此,下面的内容将对所有路由以及应用程序中可能存在的任何其他路由(例如,/testpath/*/some-other-route/等)应用共享限制,这意味着每个客户端每 5 秒仅处理两个请求(无论他们会调用哪个端点)。

limiter = Limiter(key_func=get_remote_address, application_limits=["2/5seconds"])
Run Code Online (Sandbox Code Playgroud)

选项2

使用 ,仅将共享限制应用于您希望的端点shared_limit。根据文档

shared_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}
Run Code Online (Sandbox Code Playgroud)

  • 如果您使用第一个选项,则可以使用例如`application_limits=["2/5seconds", "10/分钟"]`。如果使用第二个选项,您可以定义多个速率限制规则,以“;”分隔,例如“limit_value =“2/5秒;10/分钟””,或使用多个装饰器(每个规则一个)。 (2认同)