Skip to main content

Async rate limiter for FastAPI with Redis or native in-memory backend

Project description

fastapi‑easylimiter

GitHub stars GitHub forks GitHub issues GitHub license PyPI


An ASGI async rate-limiting middleware for FastAPI with Redis or in-memory caching, designed to handle auto-generated routes (e.g., FastAPI-Users) without decorators, for simplicity and performance.


Features

  • Async rate limiting
  • Optional temporary IP bans
    • Configurable threshold (default 10 violations)
    • Sliding 30-min offense window
    • 5-min ban on repeat abuse
  • Cache Backends
    • Redis (recommended for multi-instance deployments)
    • In-Memory (single worker dev)
  • Path-based rules
    • Supports multi-rule prefix matching
    • Global and per-route limits
  • Standard rate-limit headers
    • X-RateLimit-Limit
    • X-RateLimit-Remaining
    • X-RateLimit-Reset
    • Retry-After on 429 responses
  • Proxy Aware
    • Uses 'X-Forwarded-For' only when the sender is trusted
    • Rejects spoofed XFF headers
    • Supports 'CF-Connecting-IP' from Cloudflare, verified against CF CIDRs
    • Fallback to ASGI scope["client"] if no trusted headers exist
  • Zero dependencies beyond Redis client
    • Starlette-style ASGI middleware
  • Custom responses
    • HTMLResponse for browser clients
    • JSONResponse for API clients

Installation

pip install fastapi-easylimiter

Usage

from fastapi import FastAPI
from fastapi_easylimiter import AsyncRedisBackend, InMemoryBackend, RateLimiterMiddleware
import redis.asyncio as redis_async

app = FastAPI()

REDIS_URL = "redis://localhost:6379/0"

# Redis backend (recommended for multi-instance deployments)
redis_client = redis_async.from_url(REDIS_URL, decode_responses=True)
backend = AsyncRedisBackend(redis_client)

# Or for single-instance/local development:
# backend = InMemoryBackend()

rules = {
    "/": {"limit": 600, "period": 60},          # GLOBAL: 600 req/min per IP
    "/api/": {"limit": 10, "period": 1},
    "/api/users": {"limit": 1, "period": 2},
}

app.add_middleware(
    RateLimiterMiddleware,
    rules=rules,
    backend=backend,
    trusted_proxies=[""],     # OPTIONAL: your proxy IPs
    cloudflare=False,         # OPTIONAL: enable CF-Connecting-IP
    enable_bans=True,         # OPTIONAL: enable temporary bans
    ban_threshold=15,         # Violations before ban
    ban_duration=300,         # Ban length in seconds
    offenses_ttl=900,         # Offense counting window
    ban_page="<p>Your IP has been temporarily banned due to excessive requests.</p>", # OPTIONAL custom HTML
    rate_page="<p>Too many requests. Please try again later.</p>", # OPTIONAL custom HTML
)

Example: /api/users/me matches /api/users and /api. If any rule is exceeded → 429 returned.


Redis Lua Script (atomic)

local c = redis.call('INCR', KEYS[1])
if c == 1 then redis.call('EXPIRE', KEYS[1], ARGV[2]) end

Redis Key Patterns

Key Pattern Example Purpose
rl:{client_ip}:{prefix} rl:203.0.113.5:/api Rate-limit counter per IP+prefix
ban:{client_ip} ban:203.0.113.5 Temporary ban
offenses:{client_ip} offenses:203.0.113.5 Offense counter for ban tracking

Middleware Parameters

Parameter Type Description
app ASGIApp FastAPI/ASGI app
rules dict { prefix: {"limit": int, "period": int} }
backend Redis or InMemory backend Rate-limit storage
trusted_proxies list[str] Proxies allowed to trust XFF headers
cloudflare bool Enable Cloudflare IP extraction
enable_bans bool Enable temporary IP bans
ban_threshold int Violations before ban
ban_duration int Ban length in seconds
offenses_ttl int Offense counting window in seconds
ban_page str Custom HTML ban page
rate_page str Custom HTML rate-limit page

Screenshot

fastapi-easylimiter screenshot

Contributing

Contributions and forks are always welcome! Adapt, improve, or extend for your own needs.


Support

Buy Me a Coffee


Parts of this code were generated/assisted by AI (Grok).

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_easylimiter-0.3.4.tar.gz (8.2 kB view details)

Uploaded Source

Built Distribution

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

fastapi_easylimiter-0.3.4-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_easylimiter-0.3.4.tar.gz.

File metadata

  • Download URL: fastapi_easylimiter-0.3.4.tar.gz
  • Upload date:
  • Size: 8.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.1

File hashes

Hashes for fastapi_easylimiter-0.3.4.tar.gz
Algorithm Hash digest
SHA256 125d46eecc806253111e7fa14199a17379a171314437aa79d8d7d4ef36e9c42b
MD5 503f6aef299692f464e9a138ef79b778
BLAKE2b-256 225e9108b08fc5623790e7f628befe2c59b1a137b7aa25fb1f78bd681c60e680

See more details on using hashes here.

File details

Details for the file fastapi_easylimiter-0.3.4-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_easylimiter-0.3.4-py3-none-any.whl
Algorithm Hash digest
SHA256 1dad8b713b616c33b2e585d7b117efb5a8b4b5dc38380daaccdb557f4ffd127b
MD5 e39433de60ef266e541b390f5e26db11
BLAKE2b-256 c5ce9eac93758fd8c97cbb706dd754d8f9b8d255003a01d3bf9a2e45ac96e6c3

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