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 路由中