mitlist/be/app/core/cache.py
mohamad f49e15c05c
Some checks failed
Deploy to Production, build images and push to Gitea Registry / build_and_push (pull_request) Failing after 1m24s
feat: Introduce FastAPI and Vue.js guidelines, enhance API structure, and add caching support
This commit adds new guidelines for FastAPI and Vue.js development, emphasizing best practices for component structure, API performance, and data handling. It also introduces caching mechanisms using Redis for improved performance and updates the API structure to streamline authentication and user management. Additionally, new endpoints for categories and time entries are implemented, enhancing the overall functionality of the application.
2025-06-09 21:02:51 +02:00

78 lines
2.7 KiB
Python

import json
import hashlib
from functools import wraps
from typing import Any, Callable, Optional
from app.core.redis import get_redis
import pickle
def generate_cache_key(func_name: str, args: tuple, kwargs: dict) -> str:
"""Generate a unique cache key based on function name and arguments."""
# Create a string representation of args and kwargs
key_data = {
'function': func_name,
'args': str(args),
'kwargs': str(sorted(kwargs.items()))
}
key_string = json.dumps(key_data, sort_keys=True)
# Use SHA256 hash for consistent, shorter keys
return f"cache:{hashlib.sha256(key_string.encode()).hexdigest()}"
def cache(expire_time: int = 3600, key_prefix: Optional[str] = None):
"""
Decorator to cache function results in Redis.
Args:
expire_time: Expiration time in seconds (default: 1 hour)
key_prefix: Optional prefix for cache keys
"""
def decorator(func: Callable) -> Callable:
@wraps(func)
async def wrapper(*args, **kwargs) -> Any:
redis_client = await get_redis()
# Generate cache key
cache_key = generate_cache_key(func.__name__, args, kwargs)
if key_prefix:
cache_key = f"{key_prefix}:{cache_key}"
try:
# Try to get from cache
cached_result = await redis_client.get(cache_key)
if cached_result:
# Deserialize and return cached result
return pickle.loads(cached_result)
# Cache miss - execute function
result = await func(*args, **kwargs)
# Store result in cache
serialized_result = pickle.dumps(result)
await redis_client.setex(cache_key, expire_time, serialized_result)
return result
except Exception as e:
# If caching fails, still execute the function
print(f"Cache error: {e}")
return await func(*args, **kwargs)
return wrapper
return decorator
async def invalidate_cache_pattern(pattern: str):
"""Invalidate all cache keys matching a pattern."""
redis_client = await get_redis()
try:
keys = await redis_client.keys(pattern)
if keys:
await redis_client.delete(*keys)
except Exception as e:
print(f"Cache invalidation error: {e}")
async def clear_all_cache():
"""Clear all cache entries."""
redis_client = await get_redis()
try:
await redis_client.flushdb()
except Exception as e:
print(f"Cache clear error: {e}")