Skip to main content

Flexible rate limiting for FastAPI using pyrate-limiter

Project description

fapi-limiter

License: MIT

Flexible rate limiting for FastAPI powered by pyrate-limiter.

This project is being developed with AI assistance (GitHub Copilot), but all code, design decisions, and implementation details are reviewed and validated by the author.

Installation

# pip
pip install fapi-limiter

# uv
uv add fapi-limiter

Usage

Middleware (app-wide)

Apply rate limiting to every request in the application.

from fastapi import FastAPI
from pyrate_limiter import Duration, InMemoryBucket, Limiter, Rate

from fapi_limiter import RateLimiterMiddleware

app = FastAPI()

limiter = Limiter(InMemoryBucket([Rate(10, Duration.MINUTE)]))
app.add_middleware(RateLimiterMiddleware, limiter=limiter)

Dependency (per-route)

Apply rate limiting to specific routes using FastAPI's dependency injection.

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

from fapi_limiter import RateLimiter

app = FastAPI()

limiter = Limiter(InMemoryBucket([Rate(10, Duration.MINUTE)]))


@app.get("/limited", dependencies=[Depends(RateLimiter(limiter))])
def limited():
    return {"ok": True}

Response Headers

On every request, the following headers are set:

Header Description
X-RateLimit-Limit Maximum requests allowed in the window
X-RateLimit-Remaining Requests remaining in the current window
X-RateLimit-Reset Unix timestamp (ms) when the window resets

When the limit is exceeded, 429 Too Many Requests is returned and two additional headers are set:

Header Description
Retry-After Unix timestamp (ms) after which the client may retry

Configuration

Both RateLimiterMiddleware and RateLimiter accept the same options:

Parameter Type Default Description
limiter Limiter required A pyrate-limiter Limiter instance
callback CallbackFunction default_callback Called when the limit is exceeded
identifier Callable[[Request], str] get_default_identifier Extracts a key from the request (e.g. IP + path)
blocking bool False Whether to block and wait instead of rejecting

RateLimiterMiddleware also accepts:

Parameter Type Default Description
skip SkipFunction | None None If it returns True, the request bypasses rate limiting

Custom Callback

The callback is invoked when a request is rate-limited. It receives the Request and a headers dict, and should raise an HTTPException:

from fastapi import HTTPException, Request
from fapi_limiter import RateLimiterMiddleware

def my_callback(request: Request, headers=None):
    raise HTTPException(status_code=429, detail="Slow down!", headers=headers)

app.add_middleware(RateLimiterMiddleware, limiter=limiter, callback=my_callback)

Custom Identifier

By default the identifier is {client_ip}:{path}. You can override it to key by user, API token, etc.:

def by_user(request: Request) -> str:
    return request.headers.get("X-User-Id", "anonymous") + ":" + request.url.path

app.add_middleware(RateLimiterMiddleware, limiter=limiter, identifier=by_user)

Skip Function

Use skip on RateLimiterMiddleware to bypass rate limiting for certain requests (e.g. health checks):

def skip_health(request: Request) -> bool:
    return request.url.path == "/health"

app.add_middleware(RateLimiterMiddleware, limiter=limiter, skip=skip_health)

Credits

License

MIT

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

fapi_limiter-0.1.0.tar.gz (5.2 kB view details)

Uploaded Source

Built Distribution

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

fapi_limiter-0.1.0-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

File details

Details for the file fapi_limiter-0.1.0.tar.gz.

File metadata

  • Download URL: fapi_limiter-0.1.0.tar.gz
  • Upload date:
  • Size: 5.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.3","id":"zena","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for fapi_limiter-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1189411b27a0e6fb84a50f358b9860550a2eaee94a827fb5c683f3a0d0331bd3
MD5 02ea900dbfe355daa53e30d35c64f5a3
BLAKE2b-256 791f6f833dae46d10ac44b487cd4e61d9ae8de8b7ce10120a46b45991a3353ae

See more details on using hashes here.

File details

Details for the file fapi_limiter-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: fapi_limiter-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.3","id":"zena","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for fapi_limiter-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a95b5e9aa7d2f8a0ea36e77c2237688404984095c158b6d9d6a270b9bf11ee3c
MD5 7c8b8c3e56448df78af6440bbd384aab
BLAKE2b-256 deda219a7d9b5942fef20b9d37f034a479c636020d4c0baf08b04d976efbac88

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