"""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)