"""Bot-specific rate limiter factory. Keeps the bot entrypoint free of infra imports that would break the boundary in tests/unit/test_bot_boundary.py. Redis is resolved lazily at runtime. """ from __future__ import annotations from typing import Any from ..core.logging import get_logger from ..core.rate_limit import MemoryRateLimiter, RateLimiter log = get_logger(__name__) def _redis_client(url: str) -> Any: from ..core.redis_client import get_redis_client return get_redis_client(url) async def get_rate_limiter(redis_url: str) -> RateLimiter: """Build a Redis rate limiter or fall back to memory on failure.""" redis_client = _redis_client(redis_url) try: await redis_client.ping() from ..core.rate_limit import RedisRateLimiter log.info("rate_limiter_redis_ready") return RedisRateLimiter(redis_client) except Exception as exc: log.warning("rate_limiter_redis_unavailable", error=str(exc)) try: await redis_client.aclose() except Exception: pass return MemoryRateLimiter()