admin管理员组

文章数量:1393123

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"

本文标签: pythonHow to apply a global rate limit for all routes using SlowAPI and FastAPIStack Overflow