Source code for pydotorg.core.ratelimit.middleware

r"""Rate limiting middleware configuration using Redis.

This module configures rate limiting for the application using Litestar's built-in
RateLimitConfig with Redis as the backend store. The middleware enforces per-IP
rate limits while excluding health checks, static assets, and API documentation.

Configuration:
    Rate limits are applied per client IP address. Excluded routes:

    - /health (health check endpoint)
    - /static/\* (static files)
    - /schema (OpenAPI schema)
    - /docs (API documentation)
    - /api (OpenAPI endpoint)

Usage::

    from pydotorg.core.ratelimit.middleware import create_rate_limit_config
    from pydotorg.config import settings
    from litestar.stores.redis import RedisStore

    rate_limit_config = create_rate_limit_config(settings)
    redis_store = RedisStore.with_client(url=settings.redis_url)

    app = Litestar(
        middleware=[rate_limit_config.middleware],
        stores={"rate_limit": redis_store},
        ...
    )
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from litestar.config.response_cache import ResponseCacheConfig
from litestar.middleware.rate_limit import RateLimitConfig

if TYPE_CHECKING:
    from pydotorg.config import Settings


[docs] def create_rate_limit_config(settings: Settings) -> RateLimitConfig: """Create rate limiting configuration using Redis as the backend store. Configures per-IP rate limiting with: - Redis-based persistent storage for distributed rate limiting - Automatic rate limit headers (``X-Rate-Limit-*``, ``Retry-After``) - Exclusion of health checks, static files, and API documentation - 100 requests per minute per IP (default) Note: The Redis store must be configured in the Litestar app's ``stores`` parameter:: from litestar.stores.redis import RedisStore redis_store = RedisStore.with_client(url=settings.redis_url) app = Litestar(stores={"rate_limit": redis_store}, ...) Args: settings: Application settings containing Redis connection URL Returns: RateLimitConfig: Configured rate limit middleware instance Example: >>> from pydotorg.config import settings >>> rate_limit_config = create_rate_limit_config(settings) >>> rate_limit_config.rate_limit # ("minute", 100) """ return RateLimitConfig( rate_limit=("minute", 100), store="rate_limit", exclude=[ "/health", "/static/*", "/schema", "/docs", "/api", ], )
[docs] def create_response_cache_config(settings: Settings) -> ResponseCacheConfig: """Create response cache configuration using Redis as the backend store. Configures response caching with Redis for improved performance. This is separate from rate limiting but uses the same Redis instance. Note: The Redis store must be configured in the Litestar app's `stores` parameter: >>> from litestar.stores.redis import RedisStore >>> redis_store = RedisStore.with_client(url=settings.redis_url) >>> app = Litestar(stores={"response_cache": redis_store}, ...) Args: settings: Application settings containing Redis connection URL Returns: ResponseCacheConfig: Configured response cache instance Example: >>> cache_config = create_response_cache_config(settings) >>> cache_config.default_expiration # 60 """ return ResponseCacheConfig( default_expiration=60, store="response_cache", )