debug: probe getinfo multi-path formats (comma, path[], JSON array)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 09:30:53 +02:00
parent 014af1aefe
commit a96a3d460d
+121
View File
@@ -0,0 +1,121 @@
"""Throwaway script: test SYNO.FileStation.List::getinfo with multiple paths.
Run with:
uv run python test_getinfo_multipath.py
Tests three variants for passing multiple paths to getinfo and prints the
raw DSM response for each so we know which format the API actually accepts.
"""
from __future__ import annotations
import asyncio
import json
import sys
# ── config ────────────────────────────────────────────────────────────────
# Change these to two paths that exist on your NAS (as returned by list_shares
# or list_dir — share-relative, e.g. "/dev/somefile.txt")
PATH_A = "/dev"
PATH_B = "/data"
# ──────────────────────────────────────────────────────────────────────────
async def run() -> None:
from mcp_synology_filestation.auth import AuthManager
from mcp_synology_filestation.client import FileStationClient
from mcp_synology_filestation.config import load_config
config = load_config()
auth = AuthManager(config)
async with FileStationClient(
config.base_url,
config.connection.verify_ssl,
config.connection.timeout,
) as client:
await client.query_api_info()
sid = await auth.login(client)
client.sid = sid
api = "SYNO.FileStation.List"
method = "getinfo"
api_info = client._api_cache[api]
version = api_info["maxVersion"]
url = f"{client._base_url}/webapi/{api_info['path']}"
print(
f"SYNO.FileStation.List — path={api_info.get('path')!r} "
f"v{api_info.get('minVersion')}-v{api_info.get('maxVersion')}\n"
)
additional = json.dumps(["real_path", "size", "time", "perm", "owner", "type"])
http = client._http
# ── Variant 1: comma-separated string ─────────────────────────────
print("" * 60)
print(f"Variant 1 — path='{PATH_A},{PATH_B}' (comma-separated string)")
base_params = {
"api": api,
"version": str(version),
"method": method,
"_sid": sid,
"additional": additional,
}
params_v1 = {**base_params, "path": f"{PATH_A},{PATH_B}"}
resp = await http.get(url, params=params_v1)
body = resp.json()
print(f" HTTP {resp.status_code} success={body.get('success')}")
if body.get("success"):
files = body.get("data", {}).get("files", [])
print(f" files returned: {len(files)}")
for f in files:
print(f" path={f.get('path')!r} isdir={f.get('isdir')} add={list((f.get('additional') or {}).keys())}")
else:
print(f" ERROR: {body!r}")
print()
# ── Variant 2: repeated path[] parameters ─────────────────────────
print("" * 60)
print(f"Variant 2 — path[]={PATH_A!r} & path[]={PATH_B!r} (repeated params)")
# httpx accepts a list of tuples for repeated keys
params_v2_list = list(base_params.items()) + [("path[]", PATH_A), ("path[]", PATH_B)]
resp = await http.get(url, params=params_v2_list)
body = resp.json()
print(f" HTTP {resp.status_code} success={body.get('success')}")
if body.get("success"):
files = body.get("data", {}).get("files", [])
print(f" files returned: {len(files)}")
for f in files:
print(f" path={f.get('path')!r} isdir={f.get('isdir')} add={list((f.get('additional') or {}).keys())}")
else:
print(f" ERROR: {body!r}")
print()
# ── Variant 3: JSON array ──────────────────────────────────────────
print("" * 60)
print(f"Variant 3 — path=json.dumps([{PATH_A!r}, {PATH_B!r}]) (JSON array)")
params_v3 = {**base_params, "path": json.dumps([PATH_A, PATH_B])}
resp = await http.get(url, params=params_v3)
body = resp.json()
print(f" HTTP {resp.status_code} success={body.get('success')}")
if body.get("success"):
files = body.get("data", {}).get("files", [])
print(f" files returned: {len(files)}")
for f in files:
print(f" path={f.get('path')!r} isdir={f.get('isdir')} add={list((f.get('additional') or {}).keys())}")
else:
print(f" ERROR: {body!r}")
print()
await auth.logout(client)
if __name__ == "__main__":
try:
asyncio.run(run())
except Exception as e:
print(f"Fatal: {e}", file=sys.stderr)
sys.exit(1)