Skip to main content

A Python rate limiter library for FastAPI and Flask applications

Project description

Rate Limiter

A Python rate limiter library for FastAPI and Flask applications. This library provides a simple, thread-safe rate limiting implementation using a sliding window algorithm.

PyPI version GitHub

Features

  • 🚀 Easy to use - Simple API for both FastAPI and Flask
  • 🔒 Thread-safe - Safe for concurrent requests
  • Lightweight - No external dependencies for core functionality
  • 🎯 Flexible - Support for custom key functions and exempt paths
  • 📊 Headers - Automatic rate limit headers in responses

Installation

Install the package from PyPI:

pip install python-rate-limiter

For framework-specific integrations, install with extras:

# FastAPI
pip install python-rate-limiter[fastapi]

# Flask
pip install python-rate-limiter[flask]

# Both frameworks
pip install python-rate-limiter[all]

Alternative Installation Methods

Install from GitHub (latest development version):

pip install git+https://github.com/shekhar349/rate-limiter.git

Install from local source (for development):

# Install in development mode (editable)
pip install -e .

# With extras
pip install -e ".[fastapi]"  # or [flask] or [all]

Quick Start

Note: When using decorators, import the framework-specific decorator:

  • FastAPI: Use fastapi_rate_limit
  • Flask: Use flask_rate_limit

This ensures you get the correct decorator for your framework (async for FastAPI, sync for Flask).

FastAPI

Using Middleware (Recommended)

from fastapi import FastAPI
from python_rate_limiter import FastAPIRateLimiter

app = FastAPI()

# Initialize rate limiter
limiter = FastAPIRateLimiter(
    max_requests=100,
    time_window=60.0,  # 60 seconds
    exempt_paths=["/health", "/docs"]  # Optional: exempt certain paths
)

# Add middleware
app.middleware("http")(limiter.middleware)

@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.get("/api/data")
async def get_data():
    return {"data": "some data"}

Using Decorator

from fastapi import FastAPI, Request
from python_rate_limiter import fastapi_rate_limit

app = FastAPI()

@app.get("/api/endpoint")
@fastapi_rate_limit(max_requests=10, time_window=60)
async def endpoint(request: Request):
    return {"message": "Hello"}

Custom Key Function

from fastapi import FastAPI, Request
from python_rate_limiter import fastapi_rate_limit

app = FastAPI()

def get_user_id(request: Request) -> str:
    # Extract user ID from request (e.g., from JWT token)
    return request.headers.get("X-User-ID", "anonymous")

@app.get("/api/user-data")
@fastapi_rate_limit(max_requests=50, time_window=60, key_func=get_user_id)
async def user_data(request: Request):
    return {"user_data": "..."}

Flask

Using Extension (Recommended)

from flask import Flask
from python_rate_limiter import FlaskRateLimiter

app = Flask(__name__)

# Initialize rate limiter
limiter = FlaskRateLimiter(
    max_requests=100,
    time_window=60.0,
    exempt_paths=["/health", "/static"]  # Optional: exempt certain paths
)

# Initialize with app
limiter.init_app(app)

@app.route("/")
def root():
    return {"message": "Hello World"}

@app.route("/api/data")
def get_data():
    return {"data": "some data"}

Using Decorator

from flask import Flask
from python_rate_limiter import flask_rate_limit

app = Flask(__name__)

@app.route("/api/endpoint")
@flask_rate_limit(max_requests=10, time_window=60)
def endpoint():
    return {"message": "Hello"}

Custom Key Function

from flask import Flask, request
from python_rate_limiter import flask_rate_limit

app = Flask(__name__)

def get_user_id() -> str:
    # Extract user ID from request (e.g., from session or JWT)
    return request.headers.get("X-User-ID", "anonymous")

@app.route("/api/user-data")
@flask_rate_limit(max_requests=50, time_window=60, key_func=get_user_id)
def user_data():
    return {"user_data": "..."}

Core API

RateLimiter

The core rate limiter class can be used independently:

from python_rate_limiter import RateLimiter

limiter = RateLimiter(max_requests=100, time_window=60.0)

# Check if request is allowed
is_allowed, retry_after = limiter.is_allowed("user_ip_address")
if not is_allowed:
    print(f"Rate limit exceeded. Retry after {retry_after} seconds")

# Or raise exception
try:
    limiter.check_rate_limit("user_ip_address")
except RateLimitExceeded as e:
    print(f"Rate limit exceeded. Retry after {e.retry_after} seconds")

# Get remaining requests
remaining = limiter.get_remaining("user_ip_address")

# Reset rate limit
limiter.reset("user_ip_address")  # Reset specific key
limiter.reset()  # Reset all keys

Response Headers

The library automatically adds rate limit headers to responses:

  • X-RateLimit-Limit: Maximum number of requests allowed
  • X-RateLimit-Remaining: Number of remaining requests
  • X-RateLimit-Reset: Unix timestamp when the rate limit resets
  • Retry-After: Seconds to wait before retrying (when rate limit exceeded)

Error Responses

When rate limit is exceeded, the library returns:

  • Status Code: 429 Too Many Requests
  • Response Body:
    {
      "error": "Rate limit exceeded",
      "retry_after": 45.2,
      "message": "Too many requests. Please try again later."
    }
    

Configuration Options

FastAPIRateLimiter / FlaskRateLimiter

  • max_requests (int): Maximum number of requests allowed (default: 100)
  • time_window (float): Time window in seconds (default: 60.0)
  • key_func (Callable): Function to extract key from request (default: uses IP address)
  • exempt_paths (list[str]): List of path patterns to exempt from rate limiting

Rate Limiter Algorithm

The library uses a sliding window algorithm, which provides accurate rate limiting by tracking individual request timestamps within the time window.

Examples

See the examples/ directory for complete working examples.

License

MIT License

Contributing

Contributions are welcome! Please feel free to submit a Pull Request on GitHub.

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

python_rate_limiter-1.0.0.tar.gz (9.3 kB view details)

Uploaded Source

Built Distribution

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

python_rate_limiter-1.0.0-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

Details for the file python_rate_limiter-1.0.0.tar.gz.

File metadata

  • Download URL: python_rate_limiter-1.0.0.tar.gz
  • Upload date:
  • Size: 9.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for python_rate_limiter-1.0.0.tar.gz
Algorithm Hash digest
SHA256 4bde37f0d51e799908ad86ac8746f5ce616ff08604945c2da561ffaa5e1dffd5
MD5 520de570d05f96fd47f28f46795af22f
BLAKE2b-256 aad7eda6cf9db6d76ad23a4c912b1f03ab934c1e778456289eb13a4ece7fed20

See more details on using hashes here.

File details

Details for the file python_rate_limiter-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for python_rate_limiter-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6de774945b2cf5d3dc97d04d430b2498007f854a62e995add8a3c3f526562d36
MD5 0a480bb05eac4f2e4f2653c676fed65a
BLAKE2b-256 db0386a2609dcb9214483379822a0b62084c15ff0161dabf7de75dc93af2434b

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