""" 系统状态 API 端点 提供 GET /api/system/status。 """ import os import logging from pathlib import Path from fastapi import APIRouter from app.config.settings import settings logger = logging.getLogger(__name__) router = APIRouter() def _detect_huggingface_environment() -> dict: """检测 HuggingFace 环境 只输出非敏感摘要,不记录密钥或敏感环境变量。 Returns: 包含 is_huggingface 和环境摘要的字典 """ # 检测 HuggingFace 相关环境变量 hf_indicators = [ "SPACE_ID", "SPACE_REPO_ID", "SPACE_SDK", "HF_HOME", "HUGGINGFACE_HUB_TOKEN", ] detected_vars = [] for var in hf_indicators: if os.environ.get(var): detected_vars.append(var) is_huggingface = len(detected_vars) > 0 return { "is_huggingface": is_huggingface, "detected_indicators": detected_vars, "note": "HuggingFace 环境检测基于环境变量,不记录敏感值", } def _get_dependency_policy() -> dict: """获取依赖策略 Returns: 依赖策略描述 """ return { "check_only": True, "install_disabled": True, "description": "只检查依赖是否满足,不执行安装操作", "supported_operators": ["==", ">=", "<=", ">", "<"], "limitations": "复杂依赖解析有限,覆盖常见 ==/>=/<= 和包缺失", } def _get_unsupported_actions() -> list: """获取不支持的操作列表 Returns: 不支持的操作描述列表 """ return [ { "action": "install", "description": "页面不支持运行时安装插件", "reason": "插件随部署注入", }, { "action": "uninstall", "description": "页面不支持卸载插件", "reason": "插件随部署注入", }, { "action": "restart", "description": "页面不支持重启服务", "reason": "HuggingFace Spaces 自动管理", }, { "action": "validate_git", "description": "页面不支持 Git 仓库校验", "reason": "插件随部署注入", }, ] def _get_deployment_instructions() -> dict: """获取部署说明 Returns: 部署说明 """ return { "platform": "HuggingFace Spaces", "plugin_injection": "插件通过部署时注入,不支持运行时安装", "directory": str(settings.PLUGINS_DIR), "state_file": str(settings.DATA_DIR / "plugin_state.json"), "notes": [ "插件目录在部署时创建", "状态文件保存用户启停状态", "HuggingFace 未启用持久存储时,状态文件可能随重建丢失", ], } def _get_storage_summary() -> dict: """获取存储摘要 Returns: 存储风险和状态 """ data_dir = settings.DATA_DIR state_file = data_dir / "plugin_state.json" return { "data_directory": str(data_dir), "state_file_exists": state_file.exists(), "persistent_storage_warning": "HuggingFace 未启用持久存储时,data/ 目录可能随 Space 重建丢失", } @router.get("/status") async def get_system_status(): """获取系统状态 Returns: 包含环境、插件目录、依赖策略、部署说明、不支持动作、存储风险和 MCP 摘要的字典 """ # 检测 HuggingFace 环境 environment = _detect_huggingface_environment() # 获取插件摘要 try: from app.plugins.manager import get_plugin_manager manager = get_plugin_manager() plugin_summary = manager.get_system_plugin_summary() except Exception as e: logger.warning(f"获取插件摘要失败: {e}") plugin_summary = { "total": 0, "enabled": 0, "disabled": 0, "error": 0, "plugin_directory": str(settings.PLUGINS_DIR), } # 获取 MCP 摘要 try: from app.mcp.plugin_registry import get_plugin_registry registry = get_plugin_registry() mcp_status = registry.get_mcp_status() mcp_summary = { "total_tools": mcp_status["total_tools"], "available_tools": mcp_status["available_tools"], "unavailable_tools": mcp_status["unavailable_tools"], } except Exception as e: logger.warning(f"获取 MCP 摘要失败: {e}") mcp_summary = { "total_tools": 0, "available_tools": 0, "unavailable_tools": 0, } return { "environment": environment, "plugin_directory": str(settings.PLUGINS_DIR), "plugin_summary": plugin_summary, "dependency_policy": _get_dependency_policy(), "deployment_instructions": _get_deployment_instructions(), "unsupported_actions": _get_unsupported_actions(), "storage_summary": _get_storage_summary(), "mcp_summary": mcp_summary, }