Skip to main content

A request rate limiter for fastapi

Project description

fastapi-limiter

pypi license workflows workflows

Introduction

FastAPI-Limiter is a rate limiting tool for fastapi routes, powered by pyrate-limiter.

Install

Just install from pypi

> pip install fastapi-limiter

Quick Start

FastAPI-Limiter is simple to use, which just provides a dependency RateLimiter. The following example allows 2 requests per 5 seconds on route /.

import uvicorn
from fastapi import Depends, FastAPI
from pyrate_limiter import Duration, Limiter, Rate

from fastapi_limiter.depends import RateLimiter

app = FastAPI()

@app.get(
    "/",
    dependencies=[Depends(RateLimiter(limiter=Limiter(Rate(2, Duration.SECOND * 5))))],
)
async def index():
    return {"msg": "Hello World"}


if __name__ == "__main__":
    uvicorn.run("main:app", reload=True)

Usage

RateLimiter

RateLimiter accepts the following parameters:

  • limiter: A pyrate_limiter.Limiter instance that defines the rate limiting rules.
  • identifier: A callable to identify the request source, default is by IP + path.
  • callback: A callable invoked when the rate limit is exceeded, default raises HTTPException with 429 status code.
  • blocking: Whether to block the request when the rate limit is exceeded, default is False.

identifier

Identifier of route limit, default is ip + path, you can override it such as userid and so on.

async def default_identifier(request: Union[Request, WebSocket]):
    forwarded = request.headers.get("X-Forwarded-For")
    if forwarded:
        ip = forwarded.split(",")[0]
    elif request.client:
        ip = request.client.host
    else:
        ip = "127.0.0.1"
    return ip + ":" + request.scope["path"]

callback

Callback when rate limit is exceeded, default raises HTTPException with 429 status code.

def default_callback(*args, **kwargs):
    raise HTTPException(
        HTTP_429_TOO_MANY_REQUESTS,
        "Too Many Requests",
    )

Multiple limiters

You can use multiple limiters in one route.

@app.get(
    "/multiple",
    dependencies=[
        Depends(RateLimiter(limiter=Limiter(Rate(1, Duration.SECOND * 5)))),
        Depends(RateLimiter(limiter=Limiter(Rate(2, Duration.SECOND * 15)))),
    ],
)
async def multiple():
    return {"msg": "Hello World"}

Note that you should keep the stricter limiter (lower seconds/times ratio) first.

Skip rate limiting

You can use the skip_limiter decorator to skip rate limiting for a specific route.

from fastapi_limiter.decorators import skip_limiter

@app.get(
    "/skip",
    dependencies=[Depends(RateLimiter(limiter=Limiter(Rate(1, Duration.SECOND * 5))))],
)
@skip_limiter
async def skip_route():
    return {"msg": "This route skips rate limiting"}

Rate limiting within a websocket

While the above examples work with REST requests, FastAPI also allows easy usage of websockets, which require a slightly different approach.

Because websockets are likely to be long lived, you may want to rate limit in response to data sent over the socket.

You can do this by rate limiting within the body of the websocket handler:

from fastapi_limiter.depends import WebSocketRateLimiter

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    ratelimit = WebSocketRateLimiter(limiter=Limiter(Rate(1, Duration.SECOND * 5)))
    while True:
        try:
            data = await websocket.receive_text()
            await ratelimit(websocket, context_key=data)  # NB: context_key is optional
            await websocket.send_text("Hello, world")
        except HTTPException:
            await websocket.send_text("Hello again")

License

This project is licensed under the Apache-2.0 License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_limiter-0.2.0.tar.gz (7.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_limiter-0.2.0-py3-none-any.whl (5.2 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_limiter-0.2.0.tar.gz.

File metadata

  • Download URL: fastapi_limiter-0.2.0.tar.gz
  • Upload date:
  • Size: 7.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for fastapi_limiter-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b042259f6280056b5b2b3f506edd76c8e0648d7a5ce86c3485216a4a0fd0ec14
MD5 dace3c5df5d0228a4d79a38d549bd6db
BLAKE2b-256 b73281f64b69a79345caca0a90d1601ae7c84c39438145793514ee82daac4fc6

See more details on using hashes here.

File details

Details for the file fastapi_limiter-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_limiter-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e576ebb29cc9614c2f38471c60ed0e849024e9a1b7a2aeb4c2a31a6d708b4aea
MD5 c46e3ccc6bf748fb8edde589df9bd2fa
BLAKE2b-256 c49b35278a18254f187d55bb450ded6bc9a59c7b3010d164e1796f3dfb7aa73d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page