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.3.tar.gz (8.1 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.3-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: fastapi_easylimiter-0.3.3.tar.gz
  • Upload date:
  • Size: 8.1 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.3.tar.gz
Algorithm Hash digest
SHA256 eb5f6c826af35abd6697c663c5e7d020467a55464d8c82dee5d3ee4ef273143b
MD5 71482fdad8ab7d0f685633c7460eef23
BLAKE2b-256 08de3540a9c3794b3c2f4c7e25ca01f7ab5cff5b77fb909030f6d6905af7b4cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fastapi_easylimiter-0.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 9c21722c11b7eb17248305f25ecba2975a937fbb6936d37aac3f08c6912d262e
MD5 6fc6ce8a0ca9b9e89bd3b1e673dc2e0e
BLAKE2b-256 8be47b5c40b26df0ff98e03e67f82f903f6b04e62e5e3e7ea080d2c55d03e1bc

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