Utilities and Helpers
Relevant source files
The following files were used as context for generating this wiki page:
Utilities and helpers in FastLimit provide the foundational logic required for rate limit string parsing, secure key generation, time window alignment, and request object inspection. These functions ensure that the core rate-limiting algorithms receive standardized inputs and that Redis keys remain isolated and secure across different tenants and identifiers.
The utility module focuses on pure Python functionality that does not require an active Redis connection, making it highly testable and performant for high-frequency operations. It handles critical tasks such as URL-encoding key components to prevent collisions and hashing long keys to maintain Redis performance.
Rate String Parsing and Cost Calculation
The project uses a string-based format to define rate limits (e.g., "100/minute"). The parse_rate utility is responsible for decomposing these strings into numeric requests and window durations.
Rate Parsing Logic
The parse_rate function identifies the number of allowed requests and maps the time period (second, minute, hour, day) to its equivalent value in seconds. It supports both singular and plural forms (e.g., "second" or "seconds") and is case-insensitive.
This diagram shows the logical flow of converting a human-readable rate string into numeric values used by the backend.
Sources: fastlimit/utils.py:11-64, tests/test_utils.py:24-87
Cost Calculation
For algorithms like Token Bucket, the system calculates the "cost" of time relative to the rate. The calculate_cost function determines how much a single request represents in terms of the rate's units.
| Function | Input | Output | Purpose |
|---|---|---|---|
parse_rate | str (e.g., "10/s") | tuple[int, int] | Converts string to (requests, window_seconds). |
calculate_cost | requests, window | float | Calculates cost per unit of time for bucket refills. |
Sources: fastlimit/utils.py:214-232, tests/test_utils.py:317-340
Secure Key Generation and Hashing
FastLimit implements a sophisticated key generation strategy to prevent collisions between different identifiers (e.g., avoiding collisions between a user ID "user:123" and "user_123").
Key Composition
Keys are generated by combining a prefix, a unique identifier, a tenant type, and a time window. To ensure security, identifiers are URL-encoded. If the resulting key exceeds a specific length (default 200 characters), it is hashed using SHA-256 to ensure Redis key efficiency while maintaining uniqueness.
The key generation process ensures that special characters do not cause key collisions or Redis command injection.
Sources: fastlimit/utils.py:126-160, fastlimit/utils.py:183-211, tests/test_security.py:22-68
Key Sanitization Features
- Collision Prevention: Uses
_url_encode_key_componentto encode colons, spaces, and Redis special characters (*,?,[,]). - Deterministic Hashing: Long keys are hashed consistently so the same identifier always maps to the same Redis key.
- Prefix Preservation: When hashing, the system retains the
ratelimit:prefix to allow for easy debugging and manual inspection in Redis.
Sources: fastlimit/utils.py:92-123, tests/test_utils.py:277-314
Time Window Management
For Fixed Window and Sliding Window algorithms, time must be aligned to specific boundaries to ensure consistent limiting across distributed instances.
Window Alignment
The get_time_window helper aligns a given timestamp to the start of its current period. For example, if the window is 60 seconds, any timestamp within a specific minute will be floored to the start of that minute.
This sequence ensures that multiple application instances agree on the current window boundary.
Sources: fastlimit/utils.py:163-180, tests/test_utils.py:219-274
Request Extraction and IP Detection
When using decorators or middleware, FastLimit must automatically determine the rate limit key if one is not provided. This involves inspecting the ASGI/FastAPI request object.
IP Discovery Logic
The _get_default_key function attempts to find the client's IP address. It prioritizes the direct connection IP but can be configured to trust proxy headers (X-Forwarded-For, X-Real-IP) if the application is behind a trusted reverse proxy.
| Header Source | Priority | Description |
|---|---|---|
request.client.host | 1 | Direct connection IP (Most Secure). |
X-Forwarded-For | 2 | Trusted only if trust_proxy_headers=True. Uses first IP in chain. |
X-Real-IP | 3 | Trusted only if trust_proxy_headers=True. |
ip:unknown | Fallback | Used if no IP information can be extracted. |
Sources: fastlimit/decorators.py:194-235, tests/test_security.py:118-181
Parameter Extraction
The _extract_request helper facilitates the decorator logic by searching through function arguments to find the Request object required for context-aware rate limiting.
Sources: fastlimit/decorators.py:101-131
Conclusion
The utilities and helpers form the backbone of FastLimit's reliability. By centralizing complex logic like rate parsing and secure key generation, the library maintains a strict separation between algorithm execution and data preparation, ensuring that the system is both secure against identifier spoofing and efficient in its Redis operations.