Files
kplam c5d0f4c63e fix: 修复会话鉴权重构导致的测试回归
- 移除 conftest 中对 app.api.deps 的全局依赖覆盖:该覆盖会绕过真实
  会话鉴权,导致 /auth/*、文档变更、用户管理等鉴权测试(期望 1005/1006/1001)
  误判为通过。鉴权测试现走真实 UserStore/SessionStore。
- 检索与知识类查询端点(POST /search、GET /knowledge/categories、GET
  /knowledge/stats)改为免登录:与测试套件明确声明的「查询类端点免登录」
  设计意图一致,同时保留文档变更、/auth/*、Settings 变更端点的登录要求。

变更文件:tests/conftest.py、app/api/v1/search.py、app/api/v1/knowledge.py
2026-08-01 00:48:42 +08:00

59 lines
1.8 KiB
Python
Raw Permalink 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.
"""检索 APIPOST /api/v1/search"""
from hashlib import sha256
from typing import Any
import structlog
from fastapi import APIRouter
from app.api.response import ApiError, ok
from app.core.retriever import Retriever
from app.models.search import SearchRequest
from app.services.redis import get_cache
logger = structlog.get_logger()
router = APIRouter(prefix="/api/v1", tags=["search"])
# 模块级懒加载单例,避免每请求重建 Qdrant/Embedding client
_retriever: Retriever | None = None
def _get_retriever() -> Retriever:
global _retriever
if _retriever is None:
_retriever = Retriever()
return _retriever
def _cache_key(request: SearchRequest) -> str:
"""检索缓存键:query + top_k + summarize 的短哈希(三者均影响结果集,需参与键计算)"""
digest = sha256((request.query + "|" + str(request.top_k) + "|" + str(request.summarize)).encode()).hexdigest()[:16]
return f"search:{digest}"
@router.post("/search")
async def search(request: SearchRequest) -> dict[str, Any]:
"""分层检索入口,返回统一包装的 SearchResponse
先查 Redis 缓存:命中直接返回缓存的响应;未命中走检索流程并回写缓存。
缓存读写失败均降级为无缓存行为,不影响检索。
"""
cache_key = _cache_key(request)
cached = await get_cache().get_json(cache_key)
if cached is not None:
logger.info("检索缓存命中", query=request.query, cache_key=cache_key)
return cached
try:
response = await _get_retriever().search(request)
except ApiError:
raise
except Exception as exc:
logger.exception("检索失败", query=request.query)
raise ApiError(2000, f"检索失败: {exc}") from exc
result = ok(response.model_dump())
await get_cache().set_json(cache_key, result)
return result