mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-22 13:05:18 +00:00
本次提交包含多项优化: 1. 移除大量冗余的文件头注释与过时的from __future__导入 2. 将CRUD的list方法统一重命名为get_list保持接口一致 3. 修复前后端状态字段类型不匹配问题,将string类型status改为number 4. 修正前端文案错别字,将"代办事项"修正为标准写法 5. 更新sqlalchemy版本并调整依赖配置 6. 新增缓存工具类替代fastapi-cache2,重构缓存调用逻辑 7. 新增开源授权函生成相关工具与数据库字段支持 8. 为多个业务模块添加防重复提交loading状态 9. 修复邮件模型的外键关联缺失问题 10. 优化pdf生成工具的导入时机与文档注释
55 lines
1.7 KiB
Python
55 lines
1.7 KiB
Python
"""轻量 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)
|