Skip to main content

FastAPI rate limiter

This package adds a rate limiter to FastAPI using Redis.

Installation

First install Redis, then install the package using:

pip install fastapi-user-limiter

Usage

All the examples below can be found in example.py (use uvicorn example:app --reload to run).

Single and multiple rate limiters

You can use the rate_limit function as a FastAPI Dependency to add one or several rate limiters to an endpoint:

from fastapi_user_limiter.limiter import rate_limiter
from fastapi import FastAPI, Depends

app = FastAPI()


# Max 2 requests per 5 seconds
@app.get("/single",
         dependencies=[Depends(rate_limiter(2, 5))])
async def read_single():
    return {"Hello": "World"}


# Max 1 requests per second and max 3 requests per 10 seconds
@app.get("/multi/{some_param}", dependencies=[
    Depends(rate_limiter(1, 1)),
    Depends(rate_limiter(3, 10))
])
async def read_multi(some_param: str):
    return {"Hello": f"There {some_param}"}

Router/API-wide rate limits

You can also add a router-wide (or even API-wide) rate limiter that applies to all endpoints taken together, rather than per-endpoint:

from fastapi_user_limiter.limiter import rate_limiter
from fastapi import Depends, APIRouter

# The rate limiter in the router applies to the two endpoints together.
# If a request is made to /single, a request to /single2 within the next 
# 3 seconds will result in a "Too many requests" error.

# This rate limiter must have a custom path value, preferably 
# the same as the router's prefix value.
router = APIRouter(
    prefix='/router',
    dependencies=[Depends(rate_limiter(1, 3,
                                       path='/router'))]
)


# Each endpoint also has its own, separate rate limiter
@router.get("/single",
            dependencies=[Depends(rate_limiter(3, 20))])
async def read_single_router():
    return {"Hello": "World"}


@router.get("/single2",
            dependencies=[Depends(rate_limiter(5, 60))])
async def read_single2_router():
    return {"Hello": "There"}

Per-user rate limits

By default, rate limits are applied per host (i.e. per IP address). However, you may want to apply the rate limits on a per-user basis, especially if your API has authentication. To do so, you can pass a custom async callable to the user argument of rate_limiter, which extracts the username from the request headers:

from fastapi_user_limiter.limiter import rate_limiter
from fastapi import Depends, FastAPI

app = FastAPI()


def get_user(headers, path):
    # The username is assumed to be a bearer token,
    # contained in the 'authorization' header.
    username = headers['authorization'].replace('Bearer ', '')
    return username

# 3 requests max per 20 seconds, per user
@app.post("/auth",
          dependencies=[Depends(rate_limiter(3, 20,
                                             user=get_user))])
async def read_with_auth(data: dict):
    return {'input': data}

User-based rate limit overrides

The async callable introduced above can be used to override max_requests and/or window values for specific users by returning a dict instead of a str. In the example below, the callable overrides and increases the value of max_requests for the user "admin" and for the endpoint /auth:

from fastapi_user_limiter.limiter import rate_limiter
from fastapi import Depends, FastAPI
from starlette.datastructures import Headers, URL


app = FastAPI()


# The user callable can return either of these two:
# A. One single string containing the username
# B. A dictionary that maps the key "username" to the username (obligatory), plus two optional keys:
#     i. "max_requests": overriding the endpoint's original max_requests value for this particular user
#     ii. "window": overriding the endpoint's original window value for this particular user
# Provide a None to "max_requests" or "window" in order to disable rate limiting (for the given
# user and endpoint).
# If a dictionary without a "username" key is provided, an AssertionError is raised.

async def get_user_with_override(headers: Headers, path: str):
    # This user callable returns a dictionary and overrides max_requests for the user "admin"
    # when the endpoint's URL is '/auth'.
    username = headers['authorization'].replace('Bearer ', '')
    result_dict = {"username": username}
    if username == 'admin' and path == '/auth':
        result_dict['max_requests'] = 7
    return result_dict

# 3 requests max per 20 seconds, per user
@app.post("/auth",
          dependencies=[Depends(rate_limiter(3, 20,
                                             user=get_user_with_override))])
async def read_with_auth(data: dict):
    return {'input': data}

Metadata

Release files for fastapi-user-limiter 1.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastapi-user-limiter 1.3.0
File Size Uploaded
fastapi_user_limiter-1.3.0.tar.gz 5.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fastapi-user-limiter 1.3.0
File Interpreter ABI Platform
fastapi_user_limiter-1.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 10.5 kB

Release files / fastapi_user_limiter-1.3.0.tar.gz

Download URL fastapi_user_limiter-1.3.0.tar.gz
Size 5.0 kB
Tags Source
SHA-256 checksum
How to use checksums
55c37e9f4c8864e0438e18a7cb24c66eddaf0333d40c0fa8df8f2375ee7cadc9
BLAKE2b-256 checksum
How to use checksums
63718c70ded6993f9b7e7c8a1fbec607e87f561215b4e1ad1bb69321564bec3d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.0.0 CPython/3.9.19

Release files / fastapi_user_limiter-1.3.0-py3-none-any.whl

Download URL fastapi_user_limiter-1.3.0-py3-none-any.whl
Size 5.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f9c4bd13d6cbbafad2ceef237448f4d95dacb3f67f2b2871b6d0d04850b25e0d
BLAKE2b-256 checksum
How to use checksums
ad32e69f34b20e43dabffeb42b6a33ced60639d25244d72e1aebb90ed1b99749
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.0.0 CPython/3.9.19

Release history Release notifications | RSS feed

This release

1.3.0 This release

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page