File size: 6,007 Bytes
e82bac2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | # -*- coding: utf-8 -*-
"""
缓存管理 API 端点
"""
import logging
from typing import List, Dict, Any, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Request
from sqlalchemy.orm import Session
# 使用新的路径导入依赖和模型
from app.core.dependencies import get_db_session # 使用 get_db_session
from app.core.cache.manager import CacheManager # 导入 CacheManager (新路径)
from app.core.database.models import CachedContent # 导入数据库模型 (新路径)
from app.api.models import CacheEntryResponse # 导入或定义缓存条目响应模型
import os # 导入 os 模块
# 获取名为 'my_logger' 的日志记录器实例
logger = logging.getLogger('my_logger')
router = APIRouter()
# 假设用户标识符可以通过请求头或其他方式获取,这里简化处理,
# 实际应用中需要根据认证方式获取 user_id
# 例如,可以从 JWT token 或 API Key 中提取 user_id
# 暂时使用一个模拟函数获取用户 ID
async def get_current_user_id(request: Request) -> str:
"""
模拟获取当前用户 ID 的依赖函数。
实际应用中需要根据认证方式实现。
"""
# 示例:从请求头获取用户 ID (不安全,仅为演示)
# user_id = request.headers.get("X-User-Id")
# if not user_id:
# raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户未认证")
# return user_id
# 暂时使用一个固定的模拟用户 ID 或从请求参数获取 (如果设计允许)
# 考虑到 ChatCompletionRequest 中有 user_id,这里可以假设从请求中获取
# 但对于独立的管理接口,通常需要独立的认证机制。
# 为了测试接口功能,暂时允许从查询参数获取,实际应移除
user_id = request.query_params.get("user_id")
if not user_id:
# 如果没有从查询参数获取,尝试从请求体(如果适用)或依赖中获取
# 这里简化处理,如果没提供就报错
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="需要提供 user_id 参数")
return user_id
@router.get("/v1/caches", response_model=List[CacheEntryResponse])
async def list_user_caches(
user_id: str = Depends(get_current_user_id), # 使用依赖获取用户 ID
db: Session = Depends(get_db_session), # 使用 get_db_session
cache_manager: CacheManager = Depends(CacheManager) # 依赖注入 CacheManager
):
"""
列出当前用户的所有缓存条目。
"""
logger.info(f"接收到列出用户 {user_id} 缓存的请求")
try:
# 从数据库查询属于该用户的所有缓存条目
# 注意:这里直接查询数据库,而不是通过 CacheManager 的方法,
# 因为 CacheManager 的方法主要针对单个缓存的操作。
# 如果 CacheManager 提供了 list_caches 方法,应优先使用。
# 暂时直接使用 SQLAlchemy 查询。
caches = db.query(CachedContent).filter(CachedContent.user_id == user_id).all()
# 将数据库模型转换为响应模型
response_data = [
CacheEntryResponse(
id=cache.id,
gemini_cache_id=cache.gemini_cache_id,
content_hash=cache.content_hash,
api_key_id=cache.api_key_id,
created_at=cache.created_at,
expires_at=cache.expires_at,
last_used_at=cache.last_used_at,
usage_count=cache.usage_count,
# content 字段可能很大,响应中不包含,如果需要详情再提供单独接口
# content=cache.content # 不在列表响应中包含 content
) for cache in caches
]
logger.info(f"成功获取用户 {user_id} 的 {len(caches)} 个缓存条目")
return response_data
except Exception as e:
logger.error(f"列出用户 {user_id} 缓存时发生错误: {e}", exc_info=True)
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="获取缓存列表失败")
@router.delete("/v1/caches/{cache_id}")
async def delete_user_cache(
cache_id: int, # 缓存条目的数据库 ID
user_id: str = Depends(get_current_user_id), # 使用依赖获取用户 ID
db: Session = Depends(get_db_session), # 使用 get_db_session
cache_manager: CacheManager = Depends(CacheManager) # 依赖注入 CacheManager
):
"""
删除指定 ID 的缓存条目。
"""
logger.info(f"接收到删除用户 {user_id} 的缓存 {cache_id} 的请求")
try:
# 首先验证该缓存条目是否属于当前用户
cache_entry = db.query(CachedContent).filter(
CachedContent.id == cache_id,
CachedContent.user_id == user_id
).first()
if not cache_entry:
logger.warning(f"用户 {user_id} 尝试删除不存在或不属于自己的缓存 {cache_id}")
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="缓存条目未找到或不属于当前用户")
# 调用 CacheManager 的 delete_cache 方法删除缓存
success = await cache_manager.delete_cache(db, cache_id)
if success:
logger.info(f"成功删除用户 {user_id} 的缓存 {cache_id}")
return {"message": f"缓存条目 {cache_id} 删除成功"}
else:
logger.error(f"删除用户 {user_id} 的缓存 {cache_id} 失败 (CacheManager 返回 False)")
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="删除缓存失败")
except HTTPException:
# 重新抛出已处理的 HTTPException
raise
except Exception as e:
logger.error(f"删除用户 {user_id} 的缓存 {cache_id} 时发生错误: {e}", exc_info=True)
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="删除缓存失败")
# TODO: 添加到主路由或 v1/v2 路由中
|