fix(web): solve p0 mapping, nested validation, and add health checks
这个提交包含在:
+46
-4
@@ -36,6 +36,15 @@ def _check_ld_paths() -> List[str]:
|
||||
return paths[:10] # 限制输出长度
|
||||
|
||||
|
||||
def _cpp_runtime_available() -> bool:
|
||||
"""检测 C++ 运行时能力(不依赖编译器)"""
|
||||
try:
|
||||
import ctypes # noqa: F401
|
||||
except Exception:
|
||||
return False
|
||||
return platform.system().lower() in {"linux", "darwin", "windows"}
|
||||
|
||||
|
||||
def collect_env_info() -> Dict[str, Any]:
|
||||
"""收集完整的环境信息"""
|
||||
compilers = {
|
||||
@@ -45,6 +54,8 @@ def collect_env_info() -> Dict[str, Any]:
|
||||
"clang++": shutil.which("clang++"),
|
||||
"cl": shutil.which("cl"), # MSVC
|
||||
}
|
||||
compile_available = any(compilers.values())
|
||||
runtime_available = _cpp_runtime_available()
|
||||
|
||||
return {
|
||||
"python": {
|
||||
@@ -64,11 +75,15 @@ def collect_env_info() -> Dict[str, Any]:
|
||||
},
|
||||
"cpp": {
|
||||
"compilers": {k: v for k, v in compilers.items() if v},
|
||||
"any_available": any(compilers.values()),
|
||||
"compile_available": compile_available,
|
||||
"runtime_available": runtime_available,
|
||||
# Backward-compatible alias (historically used as "is cpp usable")
|
||||
"any_available": runtime_available,
|
||||
},
|
||||
"ld_paths": _check_ld_paths(),
|
||||
"scipy_available": _has_module("scipy"),
|
||||
"numpy_available": _has_module("numpy"),
|
||||
"web_available": _has_module("requests"),
|
||||
}
|
||||
|
||||
|
||||
@@ -80,12 +95,33 @@ def get_available_algo_types() -> List[str]:
|
||||
if env["matlab"]["engine_available"] or env["matlab"]["oct2py_available"] or env["matlab"]["octave_cli"]:
|
||||
types.append("matlab")
|
||||
|
||||
if env["cpp"]["any_available"]:
|
||||
# C++ 运行时可用即视为可执行(编译器仅影响“从源码编译”能力)
|
||||
if env["cpp"]["runtime_available"]:
|
||||
types.append("cpp")
|
||||
|
||||
if env["web_available"]:
|
||||
types.append("web")
|
||||
|
||||
return types
|
||||
|
||||
|
||||
def check_endpoint_active(url: str, timeout: int = 5) -> Tuple[bool, str]:
|
||||
"""检查远程端点是否存活"""
|
||||
try:
|
||||
import requests
|
||||
# 对根路径发起 GET 请求进行探活
|
||||
from urllib.parse import urljoin, urlparse
|
||||
parsed = urlparse(url)
|
||||
base_url = f"{parsed.scheme}://{parsed.netloc}"
|
||||
|
||||
resp = requests.get(base_url, timeout=timeout)
|
||||
if resp.status_code < 500:
|
||||
return True, f"Active (HTTP {resp.status_code})"
|
||||
return False, f"Server Error (HTTP {resp.status_code})"
|
||||
except Exception as e:
|
||||
return False, f"Disconnected: {str(e)}"
|
||||
|
||||
|
||||
def get_actionable_suggestions() -> List[Dict[str, str]]:
|
||||
"""针对故障环境提供具体的修复指令建议"""
|
||||
env = collect_env_info()
|
||||
@@ -106,10 +142,16 @@ def get_actionable_suggestions() -> List[Dict[str, str]]:
|
||||
})
|
||||
|
||||
# C++ 建议
|
||||
if not env["cpp"]["any_available"]:
|
||||
if not env["cpp"]["runtime_available"]:
|
||||
suggestions.append({
|
||||
"target": "C++ Runtime",
|
||||
"reason": "当前 Python 环境缺少 ctypes/动态链接支持",
|
||||
"fix": "请使用包含 ctypes 的标准 Python 发行版,或联系交付方提供兼容运行环境。",
|
||||
})
|
||||
elif not env["cpp"]["compile_available"]:
|
||||
suggestions.append({
|
||||
"target": "C++ Compiler",
|
||||
"reason": "未检测到 gcc/g++/clang 等编译器",
|
||||
"reason": "未检测到 gcc/g++/clang 等编译器(仅影响“从源码编译”能力)",
|
||||
"fix": "建议安装基础构建工具: `sudo apt install build-essential`"
|
||||
})
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户