Skip to main content

sliding window rate limiter for FastAPI

Project description

⚡ fastapi-sliding-window

PyPI version Python 3.10+ License MIT Status

fastapi-sliding-window — sliding window rate limiter for FastAPI

(─‿‿─)

 ,---.                ,--.                 ,--. 
/  .-' ,--,--. ,---.,-'  '-. ,--,--. ,---. `--' 
|  `-,' ,-.  |(  .-''-.  .-'' ,-.  || .-. |,--. 
|  .-'\ '-'  |.-'  `) |  |  \ '-'  || '-' '|  | 
`--'   `--`--'`----'  `--'   `--`--'|  |-' `--' 
                                    `--'        
                                                                 
                 ,--.             ,--.,--.          ,--.  ,--.   
,--.--. ,--,--.,-'  '-. ,---.     |  |`--',--,--,--.`--',-'  '-. 
|  .--'' ,-.  |'-.  .-'| .-. :    |  |,--.|        |,--.'-.  .-' 
|  |   \ '-'  |  |  |  \   --.    |  ||  ||  |  |  ||  |  |  |   
`--'    `--`--'  `--'   `----'    `--'`--'`--`--`--'`--'  `--'   

📦 installation

pip install fastapi-sliding-window

📑 quick start

from fastapi import FastAPI, Depends
from fastapi_sliding_window import RateLimit

app = FastAPI()

@app.get("/login", dependencies=[Depends(RateLimit(requests=5, window_seconds=60))])
async def login():
    return {"status": "ok"}

🧩 features

  • 🎯 3 algorithms — Sliding Window Log (exact), Sliding Window Counter (O(1) memory), Fixed Window
  • 💾 in-memory — no Redis required, zero external dependencies
  • 🔧 two usage stylesDepends(RateLimit(...)) per-route or RateLimitMiddleware globally
  • 📝 standard headersX-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After
  • fully typedpy.typed marker included
  • 🚀 async-native — built on asyncio.Lock for thread safety

📖 usage

Depends (per-route)

from fastapi import Depends
from fastapi_sliding_window import RateLimit, Algorithm

# Sliding Window Log (default, most accurate)
@app.get("/api/data", dependencies=[
    Depends(RateLimit(requests=100, window_seconds=60))
])
async def get_data():
    return {"data": "..."}

# Fixed Window (fastest, O(1) memory)
@app.post("/api/upload", dependencies=[
    Depends(RateLimit(requests=10, window_seconds=60, algorithm=Algorithm.FIXED_WINDOW))
])
async def upload():
    return {"status": "uploaded"}

# custom key function (per-user instead of per-IP)
async def user_key(request):
    return request.headers.get("X-User-ID", "anonymous")

@app.get("/api/profile", dependencies=[
    Depends(RateLimit(requests=50, window_seconds=60, key_func=user_key))
])
async def profile():
    return {"user": "..."}

Middleware (global)

from fastapi_sliding_window import RateLimitMiddleware, Algorithm

app.add_middleware(
    RateLimitMiddleware,
    requests=100,
    window_seconds=60.0,
    algorithm=Algorithm.SLIDING_WINDOW_LOG,
    exclude_paths=["/health"],  # skip rate limiting for these paths
)

📊 algorithms

Algorithm Accuracy Memory Speed Best for
Sliding Window Log 100% O(requests/window) O(1) amortized accuracy-critical endpoints
Sliding Window Counter ~99% O(1) per key O(1) high-traffic APIs
Fixed Window ~50% (boundary burst) O(1) per key O(1) simple quotas

Sliding Window Log

Stores a timestamp for every request. Prunes entries outside the window on each check. Perfectly accurate, memory grows linearly with request volume within the window.

Sliding Window Counter

Maintains two counters (current and previous window) and computes a weighted average. Near-accurate with constant memory. Best balance of accuracy and performance.

Fixed Window

Simple counter per time bucket. Suffers from boundary burst (clients can send 2x the limit across a window boundary).


📝 HTTP headers

successful responses include:

Header Description
X-RateLimit-Limit maximum requests allowed
X-RateLimit-Remaining requests remaining in window
X-RateLimit-Reset unix timestamp when window resets
Retry-After seconds until next request is allowed (429, middleware only)

🔗 API Reference

RateLimit(requests, window_seconds, algorithm, key_func, include_headers)

FastAPI dependency for per-route rate limiting.

Parameter Type Default Description
requests int required max requests per window
window_seconds float required window duration in seconds
algorithm Algorithm SLIDING_WINDOW_LOG rate limiting algorithm
key_func KeyFunc IP-based function to extract client key
include_headers bool True add rate limit headers

RateLimitMiddleware(requests, window_seconds, algorithm, key_func, include_headers, exclude_paths)

Starlette middleware for global rate limiting.

Parameter Type Default Description
requests int 100 max requests per window
window_seconds float 60.0 window duration in seconds
algorithm Algorithm SLIDING_WINDOW_LOG rate limiting algorithm
key_func KeyFunc IP-based function to extract client key
include_headers bool True add rate limit headers
exclude_paths list[str] None paths to skip rate limiting

📜 license

MIT

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_sliding_window-0.1.0.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

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

fastapi_sliding_window-0.1.0-py3-none-any.whl (12.6 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_sliding_window-0.1.0.tar.gz.

File metadata

  • Download URL: fastapi_sliding_window-0.1.0.tar.gz
  • Upload date:
  • Size: 13.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.6

File hashes

Hashes for fastapi_sliding_window-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e8edff10de493c9bf4c942a66f2f6ba5b0d87d6253c62b05d09fec1360bd42d6
MD5 cd4ea679342148789eb4dde0d3be08cc
BLAKE2b-256 32c52cd336370c73c027a085efc1d14c94d379bb0a71d14706d66b2f8541f774

See more details on using hashes here.

File details

Details for the file fastapi_sliding_window-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_sliding_window-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1cb2a8bdbd9da26e1b88b495a14354c50277a2ce395c7b3e65c1108da64873ff
MD5 b1d609bb899c635b9d0b8d50c07791ca
BLAKE2b-256 1a692fd99d411d591c0c1f4ef7fa0121167d99e3f5d1cee04d73d077da250485

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