from __future__ import annotations import argparse import json import sys from datetime import datetime import requests def _fetch_json(session: requests.Session, url: str, timeout: int = 25) -> tuple[bool, str, dict | None]: try: response = session.get(url, timeout=timeout) response.raise_for_status() return True, f"{response.status_code}", response.json() except Exception as exc: return False, str(exc), None def _fetch_text(session: requests.Session, url: str, timeout: int = 15) -> tuple[bool, str]: try: response = session.get(url, timeout=timeout) response.raise_for_status() return True, f"{response.status_code}" except Exception as exc: return False, str(exc) def main() -> int: if hasattr(sys.stdout, "reconfigure"): try: sys.stdout.reconfigure(encoding="utf-8") except Exception: pass parser = argparse.ArgumentParser(description="domainCheck Web/API smoke test") parser.add_argument("--base-url", default="http://127.0.0.1:8100", help="domain-api base URL") parser.add_argument("--web-url", default="", help="optional domain-web URL, e.g. http://127.0.0.1:3200") parser.add_argument("--output", default="", help="optional JSON report output path") args = parser.parse_args() base_url = args.base_url.rstrip("/") session = requests.Session() checks: list[dict[str, object]] = [] endpoints = [ ("health", f"{base_url}/health", 25), ("runtime_status", f"{base_url}/api/v1/runtime/status", 25), ("runtime_preflight", f"{base_url}/api/v1/runtime/preflight", 25), # overview merges multiple heavy runtime aggregates and can legitimately # take longer than lightweight health/readiness endpoints on live load. ("dashboard_overview", f"{base_url}/api/v1/dashboard/overview", 25), ("settings_export", f"{base_url}/api/v1/settings/export", 25), ("settings_backups", f"{base_url}/api/v1/settings/backups", 25), ("detect_status", f"{base_url}/api/v1/detect/status", 25), ("imports_summary", f"{base_url}/api/v1/imports/summary", 25), ("exports", f"{base_url}/api/v1/exports", 25), ("logs_latest", f"{base_url}/api/v1/logs/latest", 25), ] for name, url, timeout in endpoints: ok, message, payload = _fetch_json(session, url, timeout=timeout) checks.append( { "name": name, "url": url, "ok": ok, "message": message, "payload_excerpt": payload if ok and name in {"health", "runtime_preflight", "settings_export"} else None, } ) if args.web_url: web_url = args.web_url.rstrip("/") ok, message = _fetch_text(session, web_url) checks.append( { "name": "web_home", "url": web_url, "ok": ok, "message": message, "payload_excerpt": None, } ) passed = all(bool(item["ok"]) for item in checks) report = { "generated_at": datetime.now().isoformat(timespec="seconds"), "base_url": base_url, "web_url": args.web_url.rstrip("/") if args.web_url else "", "ok": passed, "checks": checks, } if args.output: with open(args.output, "w", encoding="utf-8") as handle: json.dump(report, handle, ensure_ascii=False, indent=2) print(json.dumps(report, ensure_ascii=False, indent=2)) return 0 if passed else 1 if __name__ == "__main__": sys.exit(main())