SlowApi

repository·master·Indexed 24 days ago

https://github.com/laurents/slowapi

A rate limiting extension for Starlette and FastAPI, adapted from flask-limiter and wrapping the limits library. It supports synchronous and asynchronous endpoints, shared limits, and multiple backends including redis, memcached, and memory. Key features include the Limiter class for configuration, @limiter.limit and @limiter.shared_limit decorators, and two middleware options: SlowAPIMiddleware and SlowAPIASGIMiddleware.

Tokens
4K
Snippets
5
Records
32
Agent score
85%

What's inside slowapi

  1. SlowApi Features and Supported Backends

    master

    SlowApi is a rate limiting library for Starlette and FastAPI, adapted from flask-limiter. It uses the limits library for the underlying rate limiting logic.

    Key Features

    • Decorators: Supports single and multiple limit decorators on endpoint functions.
    • Endpoint Support: Works with both synchronous and asynchronous HTTP endpoints.
    • Shared Limits: Supports applying shared limits across a set of routes.
    • Backends: Supports redis, memcached, and memory backends to track limits (with memory acting as a fallback).
    • Python Compatibility: Aims to support all currently supported versions of Python.
  2. Configure storage keys with key_style

    master

    The key_style option in the Limiter constructor determines how the endpoint is identified in the storage key. This affects how URL parameters impact rate limiting.

    • key_style="url": Uses the full endpoint URL. If a route has URL parameters (e.g., /user/1 vs /user/2), they are treated as distinct limits.
    • key_style="endpoint": Uses the view function's name. If a route has URL parameters, different parameters will share the same limit because the underlying function is the same.
  3. Choose between SlowAPIMiddleware and SlowAPIASGIMiddleware

    master

    Slowapi provides two middleware options:

    1. SlowAPIMiddleware: Inherits from Starlette's BaseHTTPMiddleware.
    2. SlowAPIASGIMiddleware: A pure ASGI middleware.

    Why choose SlowAPIASGIMiddleware?

    • Better performance.
    • Built-in support for asynchronous exception handlers.
    • Avoids potential deprecation issues with Starlette's BaseHTTPMiddleware.
  4. Use Redis as a backend for the limiter

    master

    To use Redis for distributed rate limiting, provide a storage_uri to the Limiter constructor using a Redis connection string (e.g., redis://<host>:<port>/<db_number>).

    limiter = Limiter(key_func=get_remote_address, storage_uri="redis://<host>:<port>/n")
  5. Apply a global (default) limit to all routes

    master

    To apply a default rate limit to every route in your application, initialize a Limiter with default_limits, attach it to your application's state, register the _rate_limit_exceeded_handler for RateLimitExceeded exceptions, and add the SlowAPIMiddleware.

        from starlette.applications import Starlette
        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 = Starlette()
        app.state.limiter = limiter
        app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
        app.add_middleware(SlowAPIMiddleware)
    
        # this will be limited by the default_limits
        async def homepage(request: Request):
            return PlainTextResponse("Only once per minute")
    
        app.add_route("/home", homepage)
  6. Apply rate limits to Starlette or FastAPI endpoints

    master

    Use the @limiter.limit() decorator on your endpoint functions to apply rate limits.

    Important Requirement: You must explicitly include the request argument in your endpoint function signature so that slowapi can hook into the request context. If the request argument is missing, rate limiting will not work.

  7. How SlowAPI middleware handles rate limit exceptions

    master

    When a rate limit is exceeded, the middleware attempts to use the application's configured exception handler for the specific exception type.

    1. Lookup: It checks app.exception_handlers for a handler matching the exception type.
    2. Fallback: If no specific handler is found, it falls back to slowapi._rate_limit_exceeded_handler.
    3. Async/Sync Support:
      • SlowAPIMiddleware (Starlette-based) uses async_check_limits which supports both sync and async handlers.
      • SlowAPIASGIMiddleware (ASGI-based) uses async_check_limits to ensure compatibility with the ASGI lifecycle.

    If the exception handler is a coroutine but is called in a synchronous context (like WSGI), it will fallback to the default _rate_limit_exceeded_handler to avoid execution errors.

  8. Exempt routes from rate limiting

    master

    SlowAPI middleware determines whether to apply rate limits based on the route handler's identity. A request is exempt from rate limiting if:

    1. No handler is found: If the middleware cannot match the request to a specific route handler.
    2. Explicitly Exempt: The route's name (formatted as module.function_name) is present in limiter._exempt_routes.
    3. Decorator applied: The route handler has a rate-limit decorator applied directly to it (detected via limiter._route_limits). In this case, the middleware skips its check and lets the decorator handle the logic.
  9. How rate limit headers work

    master

    When headers_enabled is True, the Limiter injects several headers into the response to inform the client of their current status.

    By default, these include:

    • X-RateLimit-Limit: The maximum number of requests allowed in the window.
    • X-RateLimit-Remaining: The number of requests left in the current window.
    • X-RateLimit-Reset: The time (in seconds) until the window resets.
    • Retry-After: The time until the client can try again (often used when a 429 is returned).

    You can customize these header names using the RATELIMIT_HEADER_* configuration keys.

  10. SlowApi Limitations and Known Issues

    master

    When using SlowApi, be aware of the following limitations:

    • Explicit Request Argument: As noted in the usage guide, the request object must be passed to the endpoint function.
    • Websockets: websocket endpoints are not currently supported.