#!/usr/bin/env python3 """Runtime smoke check: site orchestrator + WESP hub (debug session 785e22).""" from __future__ import annotations import json import time import urllib.error import urllib.request from pathlib import Path LOG_PATH = Path("/Users/vlad/Documents/wesp new (1)/.cursor/debug-785e22.log") SESSION = "785e22" RUN_ID = "smoke-v1" def _log(hypothesis_id: str, location: str, message: str, data: dict) -> None: payload = { "sessionId": SESSION, "runId": RUN_ID, "hypothesisId": hypothesis_id, "location": location, "message": message, "data": data, "timestamp": int(time.time() * 1000), } LOG_PATH.parent.mkdir(parents=True, exist_ok=True) with LOG_PATH.open("a", encoding="utf-8") as fh: fh.write(json.dumps(payload, ensure_ascii=False) + "\n") def _get(url: str, timeout: float = 3.0) -> tuple[int, str]: req = urllib.request.Request(url, method="GET") try: with urllib.request.urlopen(req, timeout=timeout) as resp: return resp.status, resp.read(500).decode("utf-8", errors="replace") except urllib.error.HTTPError as exc: return exc.code, exc.read(500).decode("utf-8", errors="replace") except Exception as exc: return 0, str(exc) def _post_json(url: str, body: dict, headers: dict | None = None, timeout: float = 5.0) -> tuple[int, str]: data = json.dumps(body).encode("utf-8") hdrs = {"Content-Type": "application/json", **(headers or {})} req = urllib.request.Request(url, data=data, headers=hdrs, method="POST") try: with urllib.request.urlopen(req, timeout=timeout) as resp: return resp.status, resp.read(800).decode("utf-8", errors="replace") except urllib.error.HTTPError as exc: return exc.code, exc.read(800).decode("utf-8", errors="replace") except Exception as exc: return 0, str(exc) def _get_with_cookies(url: str, cookie_header: str, timeout: float = 5.0) -> tuple[int, str]: req = urllib.request.Request(url, method="GET", headers={"Cookie": cookie_header}) try: with urllib.request.urlopen(req, timeout=timeout) as resp: return resp.status, resp.read(800).decode("utf-8", errors="replace") except urllib.error.HTTPError as exc: return exc.code, exc.read(800).decode("utf-8", errors="replace") except Exception as exc: return 0, str(exc) def _wesp_session_cookie() -> str: data = json.dumps({"login": "admin", "password": "admin"}).encode("utf-8") req = urllib.request.Request( "http://127.0.0.1/api/auth/login", data=data, headers={"Content-Type": "application/json"}, method="POST", ) try: with urllib.request.urlopen(req, timeout=5) as resp: return resp.headers.get("Set-Cookie", "").split(";")[0] except Exception: return "" def main() -> None: install_env = Path(__file__).resolve().parents[1] / "apps/api/data/secrets/install.env" wesp_state = Path(__file__).resolve().parents[2] / "wesp/data/orchestrator_sync_state.json" db_scheme = "missing" if install_env.is_file(): for line in install_env.read_text(encoding="utf-8").splitlines(): if line.startswith("DATABASE_URL="): db_scheme = "postgresql" if "postgresql" in line else ("sqlite" if "sqlite" in line else "other") break _log("H1", "smoke:install.env", "install.env database scheme", {"scheme": db_scheme, "path": str(install_env)}) orch_cfg = {"exists": wesp_state.is_file(), "enabled": False, "has_upstream": False} if wesp_state.is_file(): try: state = json.loads(wesp_state.read_text(encoding="utf-8")) orch_cfg["enabled"] = bool(state.get("enabled")) orch_cfg["has_upstream"] = bool(state.get("upstream_url")) except json.JSONDecodeError: orch_cfg["parse_error"] = True _log("H3", "smoke:wesp-state", "WESP orchestrator sync state", orch_cfg) health_code, health_body = _get("http://127.0.0.1:8000/api/v1/health") _log("H1", "smoke:site-health", "site API health", {"status": health_code, "body": health_body[:120]}) login_code, login_body = _post_json( "http://127.0.0.1:8000/api/v1/auth/login", {"email": "admin@compton.example", "password": "Admin1234"}, headers={"Origin": "http://localhost:5173"}, ) _log( "H4", "smoke:site-login", "site API login", {"status": login_code, "ok": login_code == 200, "has_token": "access_token" in login_body}, ) wesp_code, wesp_body = _get("http://127.0.0.1/") _log("H2", "smoke:wesp-root", "WESP hub root", {"status": wesp_code, "body_prefix": wesp_body[:80]}) web_code, _ = _get("http://127.0.0.1:5173/") _log("H1", "smoke:site-web", "site web dev server", {"status": web_code}) caps_code, caps_body = _get("http://127.0.0.1:8000/api/v1/sync/capabilities") _log("H5", "smoke:sync-capabilities", "orchestrator sync API", {"status": caps_code, "body": caps_body[:120]}) cookie = _wesp_session_cookie() if cookie: ctx_code, ctx_body = _get_with_cookies("http://127.0.0.1/api/v1/orchestrator/context", cookie) ctx = {} try: ctx = json.loads(ctx_body) except json.JSONDecodeError: pass _log( "H3", "smoke:wesp-orchestrator-context", "WESP orchestrator context", { "status": ctx_code, "configured": ctx.get("configured"), "reachable": ctx.get("reachable"), "enterpriseId": ctx.get("enterpriseId"), }, ) print("Smoke complete — see debug log:", LOG_PATH) print(f" site health: {health_code}, login: {login_code}, web: {web_code}") print(f" wesp hub: {wesp_code}, install.env db: {db_scheme}, orch configured: {orch_cfg.get('has_upstream')}") if __name__ == "__main__": main()