from __future__ import annotations from pathlib import Path from typing import Any, Optional from datetime import datetime import json def log(msg: str) -> None: try: print(f"[{datetime.now().isoformat(timespec='seconds')}] {msg}", flush=True) except BrokenPipeError: raise SystemExit(0) def read_text_file(path: Path) -> str: if not path.exists(): raise FileNotFoundError(f"File non trovato: {path}") return path.read_text(encoding="utf-8").strip() def write_json_file(path: Path, obj: dict) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(obj, indent=2, ensure_ascii=False), encoding="utf-8") def load_json_schema(schema_path: Path) -> Optional[dict[str, Any]]: if not schema_path.exists(): return None try: return json.loads(schema_path.read_text(encoding="utf-8")) except Exception as e: log(f"WARNING: schema file exists but cannot be parsed: {schema_path} ({e})") return None def dump_response_debug(resp: Any, path: Path) -> None: path.parent.mkdir(parents=True, exist_ok=True) try: data = resp.model_dump() except Exception: try: data = resp.to_dict() except Exception: data = {"repr": repr(resp)} path.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding="utf-8")