Files
QMDSearch/app/api/v1/settings.py
T
kplam 2ab8b56a01 feat: 完成全量功能开发,包括前端管理后台与后端服务优化
此提交实现了完整的知识库管理系统:
1. 新增Vue3 + Antd Vue前端管理后台,包含登录、文档管理、检索、类目设置等完整页面
2. 重构后端LLM调用抽象层,支持Ollama与OpenAI兼容服务动态切换
3. 调整默认嵌入模型配置为本地bge-m3模式
4. 优化入库任务去重逻辑与缓存清理机制
5. 完善Docker镜像构建与docker-compose部署配置
6. 修复多项测试用例与兼容性问题
7. 新增运行时配置API,支持动态调整系统参数
2026-07-31 12:05:25 +08:00

115 lines
3.8 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.
"""运行时配置 APIGET/PUT /api/v1/settings、GET /api/v1/settings/schema、POST /api/v1/settings/reset
GET 任何登录用户可读;PUT/reset 需 admin。PUT 后会清空 LLM 客户端 / 解析插件 /
去重策略三处进程级缓存,使新配置立即对后续请求生效。
"""
from typing import Any
import structlog
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from app.api.response import ApiError, ok
from app.core.auth import AuthUser, get_current_user, require_admin
from app.core.dedup import invalidate_dedup_strategy_cache
from app.core.file_parser import (
list_docx_plugins,
list_ocr_plugins,
list_pdf_plugins,
invalidate_parser_plugin_cache,
)
from app.core.runtime_settings import (
RuntimeSettings,
get_runtime_settings,
reset_runtime_settings,
update_runtime_settings,
)
from app.services.llm import invalidate_llm_client_cache
logger = structlog.get_logger()
router = APIRouter(prefix="/api/v1", tags=["settings"])
class SettingsUpdateRequest(BaseModel):
"""Settings PATCH body:任意子树可缺省,缺省字段保留原值
例:{"models": {"summarize": {"model": "qwen2.5:3b"}}}、
{"parsers": {"ocr": {"plugin": "tesseract"}}}、
{"dedup": {"strategy": "simhash", "simhash_threshold": 5}}
"""
models: dict[str, Any] | None = None
parsers: dict[str, Any] | None = None
dedup: dict[str, Any] | None = None
@router.get("/settings")
async def get_settings(user: AuthUser = Depends(get_current_user)) -> dict[str, Any]:
"""返回当前 RuntimeSettings(任何登录用户可读)"""
cfg = get_runtime_settings()
return ok(cfg.model_dump(mode="json"))
@router.put("/settings")
async def update_settings(
body: SettingsUpdateRequest,
user: AuthUser = Depends(require_admin),
) -> dict[str, Any]:
"""部分更新 RuntimeSettings(仅 admin
更新成功后清空 LLM 客户端 / 解析插件 / 去重策略三处进程级缓存,
使新配置立即对后续请求生效。
"""
patch = body.model_dump(exclude_none=True)
if not patch:
raise ApiError(1001, "请求体为空,未提供任何待更新字段")
try:
cfg = update_runtime_settings(patch)
except Exception as exc:
logger.error("RuntimeSettings 更新失败", error=str(exc), exc_info=True)
raise ApiError(2000, f"配置更新失败: {exc}") from exc
# 清缓存:让后续读取拿到新配置
invalidate_llm_client_cache()
invalidate_parser_plugin_cache()
invalidate_dedup_strategy_cache()
logger.info("RuntimeSettings 已更新并清理缓存", operator=user.username)
return ok(cfg.model_dump(mode="json"))
@router.get("/settings/schema")
async def get_settings_schema(
user: AuthUser = Depends(get_current_user),
) -> dict[str, Any]:
"""返回可选插件与策略列表(前端 Settings 页渲染选项用)"""
return ok(
{
"llm_providers": ["ollama", "openai_compatible"],
"pdf_plugins": list_pdf_plugins(),
"docx_plugins": list_docx_plugins(),
"ocr_plugins": list_ocr_plugins(),
"dedup_strategies": ["none", "sha256", "simhash"],
}
)
@router.post("/settings/reset")
async def reset_settings(
user: AuthUser = Depends(require_admin),
) -> dict[str, Any]:
"""重置 RuntimeSettings 为默认值(仅 admin),同时清缓存"""
try:
cfg = reset_runtime_settings()
except Exception as exc:
logger.error("RuntimeSettings 重置失败", error=str(exc), exc_info=True)
raise ApiError(2000, f"配置重置失败: {exc}") from exc
invalidate_llm_client_cache()
invalidate_parser_plugin_cache()
invalidate_dedup_strategy_cache()
logger.info("RuntimeSettings 已重置为默认值", operator=user.username)
return ok(cfg.model_dump(mode="json"))