最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - How to apply a global rate limit for all routes using SlowAPI and FastAPI? - Stack Overflow

programmeradmin6浏览0评论

I want to configure rate limiting with SlowAPI (in-memory, without Redis Cache etc.), but I don't want to add the @limiter.limit() decorator seperately for every endpoint.

So, something I don't want to do manually would be:

@limiter.limit("5/minute")
async def myendpoint(request: Request)
    pass

So, essentially, I want to include it in a middleware:

from slowapi import Limiter

limiter = Limiter(key_func=get_remote_address)

@app.middleware("http")
async def check_request(request: Request, call_next):
    client_ip = request.client.host
    prefix = "request_rate_limiter." + client_ip

    #... (logic from slowapi to get allowed flag)
    if allowed:
        response = await call_next(request)
    return response

But I didn't find a solution on how to receive a boolean from the limiter.

How would I proceed from this and would this work?

It would be great if I could configure it for different routes and also for example depending on a user subscription (e.g. free/premium).

Thanks!

I want to configure rate limiting with SlowAPI (in-memory, without Redis Cache etc.), but I don't want to add the @limiter.limit() decorator seperately for every endpoint.

So, something I don't want to do manually would be:

@limiter.limit("5/minute")
async def myendpoint(request: Request)
    pass

So, essentially, I want to include it in a middleware:

from slowapi import Limiter

limiter = Limiter(key_func=get_remote_address)

@app.middleware("http")
async def check_request(request: Request, call_next):
    client_ip = request.client.host
    prefix = "request_rate_limiter." + client_ip

    #... (logic from slowapi to get allowed flag)
    if allowed:
        response = await call_next(request)
    return response

But I didn't find a solution on how to receive a boolean from the limiter.

How would I proceed from this and would this work?

It would be great if I could configure it for different routes and also for example depending on a user subscription (e.g. free/premium).

Thanks!

Share Improve this question edited Mar 14 at 12:02 Chris 35.5k10 gold badges104 silver badges251 bronze badges asked Mar 14 at 5:49 JanJan 311 silver badge4 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 3

To apply a global (default) limit to all routes, you could use the SlowAPIMiddleware, as shown in the example below. The relevant documentation could be found here.

Related answers could also be found here and here.

Example

from fastapi import FastAPI
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.middleware import SlowAPIMiddleware
from slowapi.errors import RateLimitExceeded

limiter = Limiter(key_func=get_remote_address, default_limits=["1/minute"])
app = FastAPI()
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
app.add_middleware(SlowAPIMiddleware)


@app.get("/")
async def main():
    return "Only once per minute"

To exempt a route from the global limit, you could use the @limiter.exempt decorator on a given route, as shown in the following example. However, it seems that, currently, the decorator would only work for endpoints defined with normal def instead of async def (it could be a bug in the relevant implementation of SlowAPI—UPDATE: The issue has been fixed, so please make sure to upgrade to the latest version of SlowAPI).

@app.get("/someroute")
@limiter.exempt
async def someroute():
    return "I'm unlimited"
发布评论

评论列表(0)

  1. 暂无评论