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-1.0.0.tar.gz (19.2 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-1.0.0-py3-none-any.whl (17.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for netrun_ratelimit-1.0.0.tar.gz
Algorithm Hash digest
SHA256 03626e7cb77fc9098a0233bf70d3d3c9ad04f22b06e8849164e3a8192e87d0c2
MD5 abd3d385394444c36043ff8cf2fb8d1f
BLAKE2b-256 44838822707032f08b5432f72ddc71c3ef7f3402e2d53aad10c4e0101179e853

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for netrun_ratelimit-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 61ebe0b5030cd67739e70c530bd2940fbbd576418e7c19c0b487c185152305c6
MD5 239e9d4f8ee6144e7adfef7ccf78f4ec
BLAKE2b-256 7b4ce337b17593b52b3acf3b17df3e0d4e8f6f504c6be790e06fc3b7263448d8

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