Files
FastapiAdmin/backend/app/core/cache_util.py
T
zhangtao 7d2367e34e refactor: 统一项目代码风格并修复多处类型与调用问题
本次提交包含多项优化:
1.  移除大量冗余的文件头注释与过时的from __future__导入
2.  将CRUD的list方法统一重命名为get_list保持接口一致
3.  修复前后端状态字段类型不匹配问题,将string类型status改为number
4.  修正前端文案错别字,将"代办事项"修正为标准写法
5.  更新sqlalchemy版本并调整依赖配置
6.  新增缓存工具类替代fastapi-cache2,重构缓存调用逻辑
7.  新增开源授权函生成相关工具与数据库字段支持
8.  为多个业务模块添加防重复提交loading状态
9.  修复邮件模型的外键关联缺失问题
10. 优化pdf生成工具的导入时机与文档注释
2026-06-21 17:34:11 +08:00

55 lines
1.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""轻量 Redis 缓存工具(替代 fastapi-cache2,兼容 redis-py"""
import hashlib
import json
from collections.abc import Callable
from functools import wraps
from typing import Any
from redis.asyncio.client import Redis
_ENABLE: bool = True
_EXPIRE: int = 300
_PREFIX: str = "fastapi-admin-cache"
_REDIS: Redis | None = None
async def init(redis: Redis, prefix: str = "fastapi-admin-cache", expire: int = 300, enable: bool = True) -> None:
global _REDIS, _PREFIX, _EXPIRE, _ENABLE
_REDIS = redis
_PREFIX = prefix
_EXPIRE = expire
_ENABLE = enable
def _build_key(namespace: str, func: Callable, *args: Any, **kwargs: Any) -> str:
raw = f"{func.__module__}:{func.__qualname__}:{args}:{kwargs}"
return f"{_PREFIX}:{namespace}:{hashlib.md5(raw.encode()).hexdigest()}"
def cache(expire: int | None = None, namespace: str = "default"):
def decorator(func: Callable):
@wraps(func)
async def wrapper(*args: Any, **kwargs: Any) -> Any:
if not _ENABLE or _REDIS is None:
return await func(*args, **kwargs)
key = _build_key(namespace, func, *args, **kwargs)
cached = await _REDIS.get(key)
if cached:
return json.loads(cached)
result = await func(*args, **kwargs)
await _REDIS.set(key, json.dumps(result), ex=expire or _EXPIRE)
return result
return wrapper
return decorator
async def clear(namespace: str | None = None) -> None:
if _REDIS is None:
return
pattern = f"{_PREFIX}:{namespace}:*" if namespace else f"{_PREFIX}:*"
keys = [key async for key in _REDIS.scan_iter(match=pattern)]
if keys:
await _REDIS.delete(*keys)