release: bump version to 0.3.0
- 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
This commit is contained in:
245
docs/api/config.rst
Normal file
245
docs/api/config.rst
Normal file
@@ -0,0 +1,245 @@
|
||||
Configuration API
|
||||
=================
|
||||
|
||||
Configuration classes and loaders for rate limiting.
|
||||
|
||||
RateLimitConfig
|
||||
---------------
|
||||
|
||||
.. py:class:: RateLimitConfig(limit, window_size=60.0, algorithm=Algorithm.SLIDING_WINDOW_COUNTER, key_prefix="ratelimit", key_extractor=default_key_extractor, burst_size=None, include_headers=True, error_message="Rate limit exceeded", status_code=429, skip_on_error=False, cost=1, exempt_when=None, on_blocked=None)
|
||||
|
||||
Configuration for a rate limit rule.
|
||||
|
||||
:param limit: Maximum requests allowed in the window. Must be positive.
|
||||
:type limit: int
|
||||
:param window_size: Time window in seconds. Must be positive.
|
||||
:type window_size: float
|
||||
:param algorithm: Rate limiting algorithm to use.
|
||||
:type algorithm: Algorithm
|
||||
:param key_prefix: Prefix for the rate limit key.
|
||||
:type key_prefix: str
|
||||
:param key_extractor: Function to extract client identifier from request.
|
||||
:type key_extractor: Callable[[Request], str]
|
||||
:param burst_size: Maximum burst size for token/leaky bucket.
|
||||
:type burst_size: int | None
|
||||
:param include_headers: Whether to include rate limit headers.
|
||||
: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 cost: Cost per request.
|
||||
:type cost: int
|
||||
:param exempt_when: Function to check if request is exempt.
|
||||
:type exempt_when: Callable[[Request], bool] | None
|
||||
:param on_blocked: Callback when request is blocked.
|
||||
:type on_blocked: Callable[[Request, Any], Any] | None
|
||||
|
||||
**Usage:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from fastapi_traffic import RateLimitConfig, Algorithm
|
||||
|
||||
config = RateLimitConfig(
|
||||
limit=100,
|
||||
window_size=60,
|
||||
algorithm=Algorithm.TOKEN_BUCKET,
|
||||
burst_size=20,
|
||||
)
|
||||
|
||||
GlobalConfig
|
||||
------------
|
||||
|
||||
.. py:class:: GlobalConfig(backend=None, enabled=True, default_limit=100, default_window_size=60.0, default_algorithm=Algorithm.SLIDING_WINDOW_COUNTER, key_prefix="fastapi_traffic", include_headers=True, error_message="Rate limit exceeded. Please try again later.", status_code=429, skip_on_error=False, exempt_ips=set(), exempt_paths=set(), headers_prefix="X-RateLimit")
|
||||
|
||||
Global configuration for the rate limiter.
|
||||
|
||||
:param backend: Storage backend for rate limit data.
|
||||
:type backend: Backend | None
|
||||
:param enabled: Whether rate limiting is enabled.
|
||||
:type enabled: bool
|
||||
:param default_limit: Default maximum requests per window.
|
||||
:type default_limit: int
|
||||
:param default_window_size: Default time window in seconds.
|
||||
:type default_window_size: float
|
||||
:param default_algorithm: Default rate limiting algorithm.
|
||||
:type default_algorithm: Algorithm
|
||||
:param key_prefix: Global prefix for all rate limit keys.
|
||||
:type key_prefix: str
|
||||
:param include_headers: Include rate limit headers by default.
|
||||
:type include_headers: bool
|
||||
:param error_message: Default error message.
|
||||
:type error_message: str
|
||||
:param status_code: Default HTTP status code.
|
||||
:type status_code: int
|
||||
:param skip_on_error: Skip rate limiting on backend errors.
|
||||
:type skip_on_error: bool
|
||||
:param exempt_ips: IP addresses exempt from rate limiting.
|
||||
:type exempt_ips: set[str]
|
||||
:param exempt_paths: URL paths exempt from rate limiting.
|
||||
:type exempt_paths: set[str]
|
||||
:param headers_prefix: Prefix for rate limit headers.
|
||||
:type headers_prefix: str
|
||||
|
||||
**Usage:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from fastapi_traffic import GlobalConfig, RateLimiter
|
||||
|
||||
config = GlobalConfig(
|
||||
enabled=True,
|
||||
default_limit=100,
|
||||
exempt_paths={"/health", "/docs"},
|
||||
exempt_ips={"127.0.0.1"},
|
||||
)
|
||||
|
||||
limiter = RateLimiter(config=config)
|
||||
|
||||
ConfigLoader
|
||||
------------
|
||||
|
||||
.. py:class:: ConfigLoader(prefix="FASTAPI_TRAFFIC")
|
||||
|
||||
Load rate limit configuration from various sources.
|
||||
|
||||
:param prefix: Environment variable prefix.
|
||||
:type prefix: str
|
||||
|
||||
.. py:method:: load_rate_limit_config_from_env(env_vars=None, **overrides)
|
||||
|
||||
Load RateLimitConfig from environment variables.
|
||||
|
||||
:param env_vars: Dictionary of environment variables. Uses os.environ if None.
|
||||
:type env_vars: dict[str, str] | None
|
||||
:param overrides: Values to override after loading.
|
||||
:returns: Loaded configuration.
|
||||
:rtype: RateLimitConfig
|
||||
|
||||
.. py:method:: load_rate_limit_config_from_json(file_path, **overrides)
|
||||
|
||||
Load RateLimitConfig from a JSON file.
|
||||
|
||||
:param file_path: Path to the JSON file.
|
||||
:type file_path: str | Path
|
||||
:param overrides: Values to override after loading.
|
||||
:returns: Loaded configuration.
|
||||
:rtype: RateLimitConfig
|
||||
|
||||
.. py:method:: load_rate_limit_config_from_env_file(file_path, **overrides)
|
||||
|
||||
Load RateLimitConfig from a .env file.
|
||||
|
||||
:param file_path: Path to the .env file.
|
||||
:type file_path: str | Path
|
||||
:param overrides: Values to override after loading.
|
||||
:returns: Loaded configuration.
|
||||
:rtype: RateLimitConfig
|
||||
|
||||
.. py:method:: load_global_config_from_env(env_vars=None, **overrides)
|
||||
|
||||
Load GlobalConfig from environment variables.
|
||||
|
||||
.. py:method:: load_global_config_from_json(file_path, **overrides)
|
||||
|
||||
Load GlobalConfig from a JSON file.
|
||||
|
||||
.. py:method:: load_global_config_from_env_file(file_path, **overrides)
|
||||
|
||||
Load GlobalConfig from a .env file.
|
||||
|
||||
**Usage:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from fastapi_traffic import ConfigLoader
|
||||
|
||||
loader = ConfigLoader()
|
||||
|
||||
# From environment
|
||||
config = loader.load_rate_limit_config_from_env()
|
||||
|
||||
# From JSON file
|
||||
config = loader.load_rate_limit_config_from_json("config.json")
|
||||
|
||||
# From .env file
|
||||
config = loader.load_rate_limit_config_from_env_file(".env")
|
||||
|
||||
# With overrides
|
||||
config = loader.load_rate_limit_config_from_json(
|
||||
"config.json",
|
||||
limit=200, # Override the limit
|
||||
)
|
||||
|
||||
Convenience Functions
|
||||
---------------------
|
||||
|
||||
.. py:function:: load_rate_limit_config(file_path, **overrides)
|
||||
|
||||
Load RateLimitConfig with automatic format detection.
|
||||
|
||||
:param file_path: Path to config file (.json or .env).
|
||||
:type file_path: str | Path
|
||||
:returns: Loaded configuration.
|
||||
:rtype: RateLimitConfig
|
||||
|
||||
.. py:function:: load_rate_limit_config_from_env(**overrides)
|
||||
|
||||
Load RateLimitConfig from environment variables.
|
||||
|
||||
:returns: Loaded configuration.
|
||||
:rtype: RateLimitConfig
|
||||
|
||||
.. py:function:: load_global_config(file_path, **overrides)
|
||||
|
||||
Load GlobalConfig with automatic format detection.
|
||||
|
||||
:param file_path: Path to config file (.json or .env).
|
||||
:type file_path: str | Path
|
||||
:returns: Loaded configuration.
|
||||
:rtype: GlobalConfig
|
||||
|
||||
.. py:function:: load_global_config_from_env(**overrides)
|
||||
|
||||
Load GlobalConfig from environment variables.
|
||||
|
||||
:returns: Loaded configuration.
|
||||
:rtype: GlobalConfig
|
||||
|
||||
**Usage:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from fastapi_traffic import (
|
||||
load_rate_limit_config,
|
||||
load_rate_limit_config_from_env,
|
||||
)
|
||||
|
||||
# Auto-detect format
|
||||
config = load_rate_limit_config("config.json")
|
||||
config = load_rate_limit_config(".env")
|
||||
|
||||
# From environment
|
||||
config = load_rate_limit_config_from_env()
|
||||
|
||||
default_key_extractor
|
||||
---------------------
|
||||
|
||||
.. py:function:: default_key_extractor(request)
|
||||
|
||||
Extract client IP as the default rate limit key.
|
||||
|
||||
Checks in order:
|
||||
|
||||
1. ``X-Forwarded-For`` header (first IP)
|
||||
2. ``X-Real-IP`` header
|
||||
3. Direct connection IP
|
||||
4. Falls back to "unknown"
|
||||
|
||||
:param request: The incoming request.
|
||||
:type request: Request
|
||||
:returns: Client identifier string.
|
||||
:rtype: str
|
||||
Reference in New Issue
Block a user