"""Redis client wrapper for caching and task queuing.""" import json import logging from typing import Optional, Any import redis from config import settings logger = logging.getLogger(__name__) _redis_client: Optional[redis.Redis] = None def get_redis_client() -> redis.Redis: """Return a singleton Redis client instance.""" global _redis_client if _redis_client is None: _redis_client = redis.from_url(settings.redis_url, decode_responses=True) return _redis_client def ping() -> bool: """Check Redis connectivity.""" try: return get_redis_client().ping() except redis.ConnectionError as exc: logger.error("Redis ping failed: %s", exc) return False def set_json(key: str, value: Any, expire: Optional[int] = None) -> None: """Store a JSON-serializable value in Redis.""" client = get_redis_client() try: client.set(key, json.dumps(value), ex=expire) except redis.RedisError as exc: logger.error("Redis set_json failed: %s", exc) raise def get_json(key: str) -> Optional[Any]: """Retrieve and deserialize a JSON value from Redis.""" client = get_redis_client() try: data = client.get(key) return json.loads(data) if data is not None else None except redis.RedisError as exc: logger.error("Redis get_json failed: %s", exc) raise def delete_key(key: str) -> int: """Delete a key from Redis. Returns number of deleted keys.""" client = get_redis_client() try: return client.delete(key) except redis.RedisError as exc: logger.error("Redis delete_key failed: %s", exc) raise