ForcePilot/backend/package/yuxi/channels/adapters/synologychat/probe.py

69 lines
2.0 KiB
Python
Raw Normal View History

"""DSM API probe and version resolution.
Discovers available APIs on the target Synology NAS and resolves the best API version to use.
"""
from __future__ import annotations
from typing import Any
import httpx
from yuxi.utils.logging_config import logger
async def probe_dsm(
http_client: httpx.AsyncClient,
base_url: str,
) -> dict[str, Any]:
try:
response = await http_client.get(
f"{base_url}/webapi/query.cgi",
params={
"api": "SYNO.API.Info",
"version": "1",
"method": "query",
"query": "SYNO.API.Auth,SYNO.Chat.External",
},
)
response.raise_for_status()
data = response.json()
if not data.get("success"):
error_code = data.get("error", {}).get("code", "unknown")
logger.error(f"DSM API probe failed: error code {error_code}")
return {}
api_info = data.get("data", {})
required_apis = ["SYNO.API.Auth", "SYNO.Chat.External"]
missing = [api for api in required_apis if api not in api_info]
if missing:
logger.error(f"Required DSM APIs not available: {missing}")
return {}
logger.info(
f"DSM API probe successful: Auth v{api_info.get('SYNO.API.Auth', {}).get('maxVersion', '?')}, "
f"Chat v{api_info.get('SYNO.Chat.External', {}).get('maxVersion', '?')}"
)
return api_info
except httpx.HTTPError as e:
logger.error(f"DSM API probe HTTP error: {e}")
return {}
except Exception as e:
logger.error(f"DSM API probe failed: {e}")
return {}
def resolve_api_version(api_info: dict[str, Any] | None, api: str) -> int:
if not api_info:
if api == "SYNO.API.Auth":
return 6
if api == "SYNO.Chat.External":
return 1
return 1
api_entry = api_info.get(api, {})
return api_entry.get("maxVersion", api_entry.get("minVersion", 1))