#!/usr/bin/env python3 """ End-to-end API checks for the HF/Docker image (same stack as Spaces). Usage: python scripts/verify_hf_stack.py [--base-url http://127.0.0.1:7860] HF_VERIFY_BASE_URL=https://your-space.hf.space python scripts/verify_hf_stack.py Or run the full Docker probe (build, run container, hit API): python scripts/verify_hf_stack.py --docker Deploy to the Hub (requires HF_TOKEN + HF_SPACE_REPO), then verify live: HF_TOKEN=... HF_SPACE_REPO=user/slug python scripts/publish_hf_space.py --verify Prove catalog + kinks + recommendations on a deployed Space (no partner flow): HF_VERIFY_BASE_URL=https://owner-slug.hf.space HF_VERIFY_MIN_KINKS=1000 \\ python scripts/verify_hf_stack.py --smoke """ from __future__ import annotations import argparse import json import os import re import subprocess import sys import time from typing import Any from urllib.error import HTTPError, URLError from urllib.request import Request, urlopen def _get(url: str, headers: dict[str, str] | None = None) -> dict[str, Any]: req = Request(url, headers=headers or {}) with urlopen(req, timeout=120) as resp: return json.loads(resp.read().decode()) def _get_text(url: str, headers: dict[str, str] | None = None) -> str: req = Request(url, headers=headers or {}) with urlopen(req, timeout=120) as resp: return resp.read().decode() def _assert_live_frontend_recs_error_shaping(root: str) -> None: """Follow index → app.js → api.js / discover.js and assert error-UI hardening is deployed.""" if os.environ.get("HF_VERIFY_SKIP_FRONTEND", "").strip().lower() in ("1", "true", "yes", "on"): print("verify_hf_stack: skipping live frontend bundle check (HF_VERIFY_SKIP_FRONTEND=1)", file=sys.stderr) return base = root.rstrip("/") html = _get_text(f"{base}/") m = re.search(r"""src=["'](/frontend/app\.js\?v=\d+)["']""", html) if not m: raise RuntimeError("GET /: expected