- Refactor Redis backend connection handling and pool management - Update algorithm implementations with improved type annotations - Enhance config loader validation with stricter Pydantic schemas - Improve decorator and middleware error handling - Expand example scripts with better docstrings and usage patterns - Add new 00_basic_usage.py example for quick start - Reorganize examples directory structure - Fix type annotation inconsistencies across core modules - Update dependencies in pyproject.toml
119 lines
3.4 KiB
ReStructuredText
119 lines
3.4 KiB
ReStructuredText
Middleware API
|
|
==============
|
|
|
|
Middleware for applying rate limiting globally across your application.
|
|
|
|
RateLimitMiddleware
|
|
-------------------
|
|
|
|
.. py:class:: RateLimitMiddleware(app, *, limit=100, window_size=60.0, algorithm=Algorithm.SLIDING_WINDOW_COUNTER, backend=None, key_prefix="middleware", include_headers=True, error_message="Rate limit exceeded. Please try again later.", status_code=429, skip_on_error=False, exempt_paths=None, exempt_ips=None, key_extractor=default_key_extractor)
|
|
|
|
Middleware for global rate limiting across all endpoints.
|
|
|
|
:param app: The ASGI application.
|
|
:type app: ASGIApp
|
|
:param limit: Maximum requests per window.
|
|
:type limit: int
|
|
:param window_size: Time window in seconds.
|
|
:type window_size: float
|
|
:param algorithm: Rate limiting algorithm.
|
|
:type algorithm: Algorithm
|
|
:param backend: Storage backend. Defaults to MemoryBackend.
|
|
:type backend: Backend | None
|
|
:param key_prefix: Prefix for rate limit keys.
|
|
:type key_prefix: str
|
|
:param include_headers: Include rate limit headers in response.
|
|
:type include_headers: bool
|
|
:param error_message: Error message when rate limited.
|
|
:type error_message: str
|
|
:param status_code: HTTP status code when rate limited.
|
|
:type status_code: int
|
|
:param skip_on_error: Skip rate limiting on backend errors.
|
|
:type skip_on_error: bool
|
|
:param exempt_paths: Paths to exempt from rate limiting.
|
|
:type exempt_paths: set[str] | None
|
|
:param exempt_ips: IP addresses to exempt from rate limiting.
|
|
:type exempt_ips: set[str] | None
|
|
:param key_extractor: Function to extract client identifier.
|
|
:type key_extractor: Callable[[Request], str]
|
|
|
|
**Basic usage:**
|
|
|
|
.. code-block:: python
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi_traffic.middleware import RateLimitMiddleware
|
|
|
|
app = FastAPI()
|
|
|
|
app.add_middleware(
|
|
RateLimitMiddleware,
|
|
limit=1000,
|
|
window_size=60,
|
|
)
|
|
|
|
**With exemptions:**
|
|
|
|
.. code-block:: python
|
|
|
|
app.add_middleware(
|
|
RateLimitMiddleware,
|
|
limit=1000,
|
|
window_size=60,
|
|
exempt_paths={"/health", "/docs"},
|
|
exempt_ips={"127.0.0.1"},
|
|
)
|
|
|
|
**With custom backend:**
|
|
|
|
.. code-block:: python
|
|
|
|
from fastapi_traffic import SQLiteBackend
|
|
|
|
backend = SQLiteBackend("rate_limits.db")
|
|
|
|
app.add_middleware(
|
|
RateLimitMiddleware,
|
|
limit=1000,
|
|
window_size=60,
|
|
backend=backend,
|
|
)
|
|
|
|
SlidingWindowMiddleware
|
|
-----------------------
|
|
|
|
.. py:class:: SlidingWindowMiddleware(app, *, limit=100, window_size=60.0, **kwargs)
|
|
|
|
Convenience middleware using the sliding window algorithm.
|
|
|
|
Accepts all the same parameters as ``RateLimitMiddleware``.
|
|
|
|
.. code-block:: python
|
|
|
|
from fastapi_traffic.middleware import SlidingWindowMiddleware
|
|
|
|
app.add_middleware(
|
|
SlidingWindowMiddleware,
|
|
limit=1000,
|
|
window_size=60,
|
|
)
|
|
|
|
TokenBucketMiddleware
|
|
---------------------
|
|
|
|
.. py:class:: TokenBucketMiddleware(app, *, limit=100, window_size=60.0, **kwargs)
|
|
|
|
Convenience middleware using the token bucket algorithm.
|
|
|
|
Accepts all the same parameters as ``RateLimitMiddleware``.
|
|
|
|
.. code-block:: python
|
|
|
|
from fastapi_traffic.middleware import TokenBucketMiddleware
|
|
|
|
app.add_middleware(
|
|
TokenBucketMiddleware,
|
|
limit=1000,
|
|
window_size=60,
|
|
)
|