Files

67 lines
1.8 KiB
Python

"""Redis cache client and helpers."""
import json
from typing import Any
import redis.asyncio as redis
from app.config import get_settings
settings = get_settings()
async def get_redis() -> redis.Redis:
"""Return a Redis client instance."""
return redis.from_url(settings.redis_url, decode_responses=True)
class CacheClient:
"""Wrapper around Redis for equipment caching."""
def __init__(self) -> None:
self._redis: redis.Redis | None = None
async def connect(self) -> None:
self._redis = await get_redis()
async def disconnect(self) -> None:
if self._redis:
await self._redis.close()
self._redis = None
async def get(self, key: str) -> Any | None:
if not self._redis:
await self.connect()
assert self._redis is not None
data = await self._redis.get(key)
if data:
return json.loads(data)
return None
async def set(self, key: str, value: Any, ttl: int = 3600) -> None:
if not self._redis:
await self.connect()
assert self._redis is not None
await self._redis.setex(key, ttl, json.dumps(value, default=str))
async def delete_pattern(self, pattern: str) -> int:
if not self._redis:
await self.connect()
assert self._redis is not None
keys = []
async for key in self._redis.scan_iter(match=pattern):
keys.append(key)
if keys:
return await self._redis.delete(*keys)
return 0
async def incr_rate(self, key: str, window: int = 60) -> int:
if not self._redis:
await self.connect()
assert self._redis is not None
count = await self._redis.incr(key)
if count == 1:
await self._redis.expire(key, window)
return count
cache = CacheClient()