Skip to main content

A rate limiter for FastAPI without using Redis.

Project description

# FastAPI Throttle

PyPI CI Python Versions License: MIT Downloads Wheel Type Hints

A lightweight, in-memory rate limiter for FastAPI applications that requires no external dependencies.

Table of Contents

Overview

FastAPI Throttle helps you control API request rates without Redis or other external services. It's designed for applications where simplicity and minimal dependencies are priorities.

Requirements

  • Python 3.8+
  • FastAPI

Installation

pip install fastapi-throttle

Quick Start

from fastapi import FastAPI, Depends
from fastapi_throttle import RateLimiter

app = FastAPI()

# Limit to 5 requests per minute
limiter = RateLimiter(times=5, seconds=60)

@app.get("/", dependencies=[Depends(limiter)])
async def root():
    return {"message": "Hello World"}

Features

  • No External Dependencies: Works without Redis or other services
  • Simple Configuration: Just specify request count and time window
  • Route-Level Control: Apply different limits to different endpoints
  • FastAPI Integration: Works with FastAPI's dependency injection system
  • Custom Keying (optional): Provide a key_func(Request) -> str to limit by user, API key, path, etc.
  • Proxy-Aware (optional): trust_proxy=True to use X-Forwarded-For when behind proxies/CDNs
  • Rate-Limit Headers (optional): Add X-RateLimit-* and Retry-After for clients

Usage Examples

Different Limits for Different Routes

from fastapi import FastAPI, Depends
from fastapi_throttle import RateLimiter

app = FastAPI()

# Public endpoint: 10 requests per minute
public_limit = RateLimiter(times=10, seconds=60)

# Sensitive endpoint: 2 requests per minute
strict_limit = RateLimiter(times=2, seconds=60)

@app.get("/public", dependencies=[Depends(public_limit)])
async def public_endpoint():
    return {"message": "Public endpoint"}

@app.get("/sensitive", dependencies=[Depends(strict_limit)])
async def sensitive_endpoint():
    return {"message": "Sensitive endpoint"}

Using with APIRouter

from fastapi import APIRouter, Depends, FastAPI
from fastapi_throttle import RateLimiter

app = FastAPI()
router = APIRouter(prefix="/api")

# Apply same rate limit to all routes in this router
api_limit = RateLimiter(times=5, seconds=30)

@router.get("/resource", dependencies=[Depends(api_limit)])
async def get_resource():
    return {"data": "Resource data"}

app.include_router(router)

Custom Key Function (limit by user or path)

from fastapi import FastAPI, Depends, Request
from fastapi_throttle import RateLimiter

app = FastAPI()

def user_key(req: Request) -> str:
    # Example: extract user-id from header or auth (for demo only)
    return req.headers.get("x-user-id", req.client.host or "unknown")

limiter = RateLimiter(times=10, seconds=60, key_func=user_key)

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

Behind proxy/CDN (trust X-Forwarded-For)

from fastapi import FastAPI, Depends
from fastapi_throttle import RateLimiter

app = FastAPI()

proxy_limit = RateLimiter(times=5, seconds=30, trust_proxy=True)

@app.get("/proxy", dependencies=[Depends(proxy_limit)])
async def proxy_route():
    return {"ok": True}

Standard rate-limit headers

from fastapi import FastAPI, Depends
from fastapi_throttle import RateLimiter

app = FastAPI()

headers_limit = RateLimiter(times=5, seconds=60, add_headers=True)

@app.get("/limited", dependencies=[Depends(headers_limit)])
async def limited():
    return {"message": "Check X-RateLimit-* headers"}

Configuration

The RateLimiter class parameters:

Parameter Type Description
times int Maximum number of requests allowed in the time window
seconds int Time window in seconds
detail str Optional custom detail message for 429 responses
key_func Callable[[Request], str] Optional custom function to compute the rate-limit key
trust_proxy bool If True, tries X-Forwarded-For for client identification (default False)
add_headers bool If True, adds X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After headers

How It Works

The rate limiter:

  1. Identifies clients by IP address
  2. Stores request timestamps in memory
  3. Removes timestamps outside the current time window
  4. Counts requests within the window
  5. Returns HTTP 429 when limit is exceeded

Notes

  • When add_headers=True, successful responses (2xx) include X-RateLimit-Limit and X-RateLimit-Remaining. On 429 responses, only Retry-After is included.
  • Use trust_proxy=True only when running behind a trusted proxy/load balancer that correctly sets X-Forwarded-For. The first IP is treated as the client.

Limitations

  • Memory Storage: Data is lost when the application restarts
  • Single-Server Only: Intended for monoliths/single-worker setups (in-memory, no cross-process sync)
  • IP-Based Identification (default): With shared IPs/proxies, prefer key_func or trust_proxy
  • Memory Usage: Can grow with number of unique clients

When to Use

FastAPI Throttle is ideal for:

  • Small to medium applications
  • Single-server deployments
  • Projects where simplicity is valued over advanced features
  • Development and testing environments

For high-traffic production applications or distributed systems, prefer a distributed rate limiter (e.g., Redis-backed). This package intentionally avoids Redis and focuses on simplicity.

Testing

pip install -r requirements.txt
pytest --cov=fastapi_throttle -q

Contributing

  • Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
  • Make sure tests pass and add tests for new features.
  • Follow the existing code style; this repo uses flake8 and pre-commit.

Roadmap

  • Middleware variant in addition to dependency-based limiter
  • (Maybe) Pluggable storage interface if a second backend is introduced later

License

MIT License. See LICENSE for details.

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_throttle-0.1.8.tar.gz (8.0 kB view details)

Uploaded Source

Built Distribution

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

fastapi_throttle-0.1.8-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_throttle-0.1.8.tar.gz.

File metadata

  • Download URL: fastapi_throttle-0.1.8.tar.gz
  • Upload date:
  • Size: 8.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.23

File hashes

Hashes for fastapi_throttle-0.1.8.tar.gz
Algorithm Hash digest
SHA256 b0867be26bf3335cae0ecb7069c5cb7d246e14dbbd51329050af7043435370ce
MD5 cc91ed43f267b91cad339f434bce6417
BLAKE2b-256 b3efb71c86ced9cabc075ed4629178960ccdaf55b56f37a5392c574b2fa4ad35

See more details on using hashes here.

File details

Details for the file fastapi_throttle-0.1.8-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_throttle-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 ba04991eae1795b13b1d3a514a6967ba4588218dc92375e4c45e12cdebe160e2
MD5 87bdeb8d01ee45e02ba93c202f993ff1
BLAKE2b-256 1581972fa6f3fd2b45fa11fd7269aa24a242dd51c093ed45937f201224cc7e85

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