Skip to main content

Distributed rate limiting with token bucket algorithm and Redis backend

Project description

netrun-ratelimit

Distributed rate limiting with token bucket algorithm and Redis backend.

Features

  • Token Bucket Algorithm: Allows bursts while maintaining average rate limits
  • Multiple Backends: In-memory for single instances, Redis for distributed systems
  • FastAPI Integration: Middleware and decorators for seamless integration
  • Async Support: Full async/await support for high-performance applications
  • Type-Safe: Complete type hints with py.typed marker

Installation

# Core package (memory backend only)
pip install netrun-ratelimit

# With Redis support
pip install netrun-ratelimit[redis]

# With FastAPI integration
pip install netrun-ratelimit[fastapi]

# All features
pip install netrun-ratelimit[all]

Quick Start

Basic Usage

from netrun_ratelimit import RateLimiter, MemoryBackend

# Create limiter (100 requests per minute)
limiter = RateLimiter(
    backend=MemoryBackend(),
    rate=100,
    period=60,
)

# Check rate limit
result = limiter.check("user:123")
if result.allowed:
    # Process request
    pass
else:
    # Rate limited
    print(f"Retry after {result.retry_after} seconds")

With Redis (Distributed)

from netrun_ratelimit import RateLimiter, RedisBackend

backend = RedisBackend(redis_url="redis://localhost:6379")
limiter = RateLimiter(backend=backend, rate=100, period=60)

# Works across multiple application instances
result = limiter.check("user:123")

FastAPI Middleware

from fastapi import FastAPI
from netrun_ratelimit import RateLimiter, MemoryBackend, RateLimitMiddleware

app = FastAPI()

limiter = RateLimiter(backend=MemoryBackend(), rate=100, period=60)

app.add_middleware(
    RateLimitMiddleware,
    limiter=limiter,
    exclude_paths=["/health", "/metrics"],
)

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

Route Decorators

from fastapi import FastAPI, Request
from netrun_ratelimit import rate_limit, limit_by_user, limit_by_api_key

app = FastAPI()

# Basic rate limit
@app.get("/api/public")
@rate_limit(rate=10, period=60)
async def public_endpoint(request: Request):
    return {"status": "ok"}

# Per-user rate limit
@app.get("/api/user")
@limit_by_user(rate=100, period=60)
async def user_endpoint(request: Request):
    return {"status": "ok"}

# Per-API-key rate limit
@app.get("/api/partner")
@limit_by_api_key(rate=1000, period=3600)
async def partner_endpoint(request: Request):
    return {"status": "ok"}

Configuration

Use environment variables or Pydantic settings:

from netrun_ratelimit import RateLimitConfig

config = RateLimitConfig(
    rate=100,              # Requests per period
    period=60,             # Period in seconds
    burst=150,             # Max burst size
    redis_url="redis://localhost:6379",
    key_prefix="myapp:",
    include_headers=True,
)

Environment variables (prefixed with RATELIMIT_):

RATELIMIT_RATE=100
RATELIMIT_PERIOD=60
RATELIMIT_REDIS_URL=redis://localhost:6379

HTTP Headers

Rate limit information is returned in standard headers:

Header Description
X-RateLimit-Limit Maximum requests per period
X-RateLimit-Remaining Remaining requests in current period
X-RateLimit-Reset Unix timestamp when limit resets
Retry-After Seconds until retry (only when limited)

Exception Handling

from netrun_ratelimit import RateLimitExceeded
from fastapi import HTTPException

try:
    result = limiter.check("user:123")
    if not result.allowed:
        raise RateLimitExceeded(
            limit=result.limit,
            retry_after=result.retry_after,
        )
except RateLimitExceeded as e:
    raise HTTPException(
        status_code=429,
        detail="Too many requests",
        headers=e.headers,
    )

Token Bucket Algorithm

The token bucket algorithm provides smooth rate limiting with burst capability:

  • Bucket starts full with burst tokens
  • Each request consumes 1 token
  • Tokens refill at rate/period tokens per second
  • Requests are denied when bucket is empty

Example: 100 req/minute with burst of 150

  • Can handle initial burst of 150 requests
  • Sustained rate limited to ~1.67 requests/second
  • Bucket refills even while processing requests

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=netrun_ratelimit

# Type checking
mypy netrun_ratelimit

# Linting
ruff check netrun_ratelimit

License

MIT License - see LICENSE file for details.

Contributing

Contributions welcome! Please read our contributing guidelines and submit pull requests to the main repository.

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

netrun_ratelimit-2.0.0.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

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

netrun_ratelimit-2.0.0-py3-none-any.whl (30.2 kB view details)

Uploaded Python 3

File details

Details for the file netrun_ratelimit-2.0.0.tar.gz.

File metadata

  • Download URL: netrun_ratelimit-2.0.0.tar.gz
  • Upload date:
  • Size: 25.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for netrun_ratelimit-2.0.0.tar.gz
Algorithm Hash digest
SHA256 79cc052f55d2caf59569416337a6d137da2a3e6ac0d94d3bab2629487f7f8ff0
MD5 6692a5ed99e9011a73627b40dff8d6c9
BLAKE2b-256 17da3a548763890c8d47551d8dde55d20b9e585cd8a395e5c91aa3f3a22534cb

See more details on using hashes here.

File details

Details for the file netrun_ratelimit-2.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for netrun_ratelimit-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 12e76424cdb5a17a6c23467961d39cb438a77692a14658232b0a9740a7f4db67
MD5 1c50db7d20741e57a99455256fba6a4a
BLAKE2b-256 25df11b5201b45a7ae868280a196894840285996535c55bf8d154f1bc927b9ac

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