"""Throwaway script: test SYNO.FileStation.List::list additional field formats. Run with: uv run python test_additional.py Reads config from the default location and credentials from the OS keyring, exactly as the MCP server does. Tests three additional variants against a real share path and prints the raw DSM response for each. """ from __future__ import annotations import asyncio import json import sys import httpx # noqa: F401 — used at runtime for the HTTP client reference # ── config ──────────────────────────────────────────────────────────────── # Change this to any share that exists on your NAS (as returned by list_shares) TEST_PATH = "/dev" # ────────────────────────────────────────────────────────────────────────── 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 info = client._api_cache.get("SYNO.FileStation.List", {}) print( f"SYNO.FileStation.List — path={info.get('path')!r} " f"v{info.get('minVersion')}-v{info.get('maxVersion')}\n" ) variants: list[tuple[str, dict]] = [ ( "1 — no additional", { "folder_path": TEST_PATH, "offset": 0, "limit": 5, "sort_by": "name", "sort_direction": "asc", }, ), ( '2 — additional="size,time" (comma-separated string)', { "folder_path": TEST_PATH, "offset": 0, "limit": 5, "sort_by": "name", "sort_direction": "asc", "additional": "size,time", }, ), ( '3 — additional=json.dumps(["size","time"]) (JSON array)', { "folder_path": TEST_PATH, "offset": 0, "limit": 5, "sort_by": "name", "sort_direction": "asc", "additional": json.dumps(["size", "time"]), }, ), ] for label, params in variants: print(f"{'─' * 60}") print(f"Variant {label}") print(f" params: {params}") try: # Call the low-level HTTP layer directly so we see the raw body, # bypassing any error-mapping in client.request() api = "SYNO.FileStation.List" method = "list" api_info = client._api_cache[api] version = api_info["maxVersion"] url = f"{client._base_url}/webapi/{api_info['path']}" req_params: dict = { "api": api, "version": str(version), "method": method, "_sid": client.sid, } req_params.update(params) http = client._http resp = await http.get(url, params=req_params) body = resp.json() print(f" HTTP {resp.status_code}") print(f" success: {body.get('success')}") if body.get("success"): data = body.get("data", {}) files = data.get("files", []) print(f" total: {data.get('total')} returned: {len(files)}") if files: first = files[0] print(f" first file keys: {list(first.keys())}") add = first.get("additional") print(f" first file additional: {add!r}") else: print(f" RAW error body: {body!r}") except Exception as exc: print(f" EXCEPTION: {exc!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)