Download scripts/configure_vercel_worker.py from Syncre/arabic-audio-reader-worker: direct link, hf CLI and curl.
- Browser
- Download file 6.29 kB
-
https://huggingface.co/spaces/Syncre/arabic-audio-reader-worker/resolve/main/scripts/configure_vercel_worker.py
- Command line
-
hf download hf://spaces/Syncre/arabic-audio-reader-worker/scripts/configure_vercel_worker.py
-
curl -L -o configure_vercel_worker.py https://huggingface.co/spaces/Syncre/arabic-audio-reader-worker/resolve/main/scripts/configure_vercel_worker.py
6.29 kB
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import shutil | |
| import subprocess | |
| import sys | |
| from dataclasses import dataclass | |
| from pathlib import Path | |
| from typing import Sequence | |
| ROOT_DIR = Path(__file__).resolve().parent.parent | |
| if str(ROOT_DIR) not in sys.path: | |
| sys.path.insert(0, str(ROOT_DIR)) | |
| from scripts.verify_site import verify_site | |
| DEFAULT_SITE_URL = "https://arabic-translator-mu.vercel.app" | |
| DIRECT_CLOUD_ENV_KEYS = ["ENABLE_DIRECT_CLOUD_TTS", "HF_API_TOKEN", "HF_TTS_MODEL", "DEFAULT_VOICE_ID"] | |
| VERCEL_COMMAND = shutil.which("vercel") or shutil.which("vercel.cmd") or "vercel" | |
| class CommandResult: | |
| command: list[str] | |
| returncode: int | |
| stdout: str | |
| stderr: str | |
| def normalize_url(value: str) -> str: | |
| return value.rstrip("/") | |
| def looks_like_hf_space(url: str) -> bool: | |
| host = url.split("://", 1)[-1].split("/", 1)[0].lower() | |
| return host == "hf.space" or host.endswith(".hf.space") | |
| def validate_worker_url(worker_url: str) -> str: | |
| worker_url = normalize_url(worker_url.strip()) | |
| if not worker_url.startswith("https://"): | |
| raise ValueError("WORKER_BASE_URL must start with https://") | |
| if "localhost" in worker_url or "127.0.0.1" in worker_url: | |
| raise ValueError("WORKER_BASE_URL must be public, not localhost") | |
| if ".vercel.app" in worker_url: | |
| raise ValueError("WORKER_BASE_URL must point at the worker, not the Vercel site") | |
| if not looks_like_hf_space(worker_url): | |
| raise ValueError("WORKER_BASE_URL should be a Hugging Face Space URL ending in .hf.space") | |
| return worker_url | |
| def run_command(command: Sequence[str], input_text: str | None = None, check: bool = True) -> CommandResult: | |
| completed = subprocess.run( | |
| list(command), | |
| input=input_text, | |
| text=True, | |
| capture_output=True, | |
| ) | |
| result = CommandResult( | |
| command=list(command), | |
| returncode=completed.returncode, | |
| stdout=completed.stdout, | |
| stderr=completed.stderr, | |
| ) | |
| if check and completed.returncode != 0: | |
| message = completed.stderr.strip() or completed.stdout.strip() or f"command failed with {completed.returncode}" | |
| raise RuntimeError(f"{' '.join(command)} failed: {message}") | |
| return result | |
| def remove_vercel_env(name: str, environment: str) -> CommandResult: | |
| result = run_command([VERCEL_COMMAND, "env", "rm", name, environment, "--yes"], check=False) | |
| combined = f"{result.stdout}\n{result.stderr}" | |
| if result.returncode != 0 and "env_not_found" not in combined and "was not found" not in combined: | |
| message = result.stderr.strip() or result.stdout.strip() or f"command failed with {result.returncode}" | |
| raise RuntimeError(f"vercel env rm {name} failed: {message}") | |
| return result | |
| def add_vercel_env(name: str, value: str, environment: str) -> CommandResult: | |
| return run_command([VERCEL_COMMAND, "env", "add", name, environment], input_text=f"{value}\n") | |
| def configure_vercel_worker( | |
| worker_url: str, | |
| site_url: str = DEFAULT_SITE_URL, | |
| code: str = "1234", | |
| environment: str = "production", | |
| redeploy: bool = True, | |
| verify: bool = False, | |
| timeout: float = 60, | |
| ) -> dict[str, object]: | |
| worker_url = validate_worker_url(worker_url) | |
| site_url = normalize_url(site_url) | |
| commands: list[CommandResult] = [] | |
| commands.append(remove_vercel_env("WORKER_BASE_URL", environment)) | |
| commands.append(add_vercel_env("WORKER_BASE_URL", worker_url, environment)) | |
| for key in DIRECT_CLOUD_ENV_KEYS: | |
| commands.append(remove_vercel_env(key, environment)) | |
| if redeploy: | |
| commands.append(run_command([VERCEL_COMMAND, "deploy", "--prod", "--yes"])) | |
| site_checks = None | |
| if verify: | |
| site_checks = [check.__dict__ for check in verify_site(site_url, code, worker_url, timeout=timeout)] | |
| return { | |
| "workerUrl": worker_url, | |
| "siteUrl": site_url, | |
| "environment": environment, | |
| "redeployed": redeploy, | |
| "verified": verify, | |
| "commands": [ | |
| { | |
| "command": result.command, | |
| "returncode": result.returncode, | |
| "stdout": result.stdout, | |
| "stderr": result.stderr, | |
| } | |
| for result in commands | |
| ], | |
| "siteChecks": site_checks, | |
| "nextCommand": ( | |
| f"python scripts\\prove_live_deployment.py {worker_url} --origin {site_url} " | |
| f"--code {code} --smoke-ocr-engine arabic" | |
| ), | |
| } | |
| def main_with_args(argv: list[str] | None = None) -> int: | |
| parser = argparse.ArgumentParser(description="Set Vercel WORKER_BASE_URL, redeploy, and optionally verify the site.") | |
| parser.add_argument("worker_url", help="Public Hugging Face Space worker URL, e.g. https://user-space.hf.space") | |
| parser.add_argument("--site-url", default=DEFAULT_SITE_URL) | |
| parser.add_argument("--code", default="1234") | |
| parser.add_argument("--environment", default="production") | |
| parser.add_argument("--no-redeploy", action="store_true") | |
| parser.add_argument("--verify", action="store_true", help="Run scripts.verify_site after redeploy.") | |
| parser.add_argument("--timeout", type=float, default=60) | |
| parser.add_argument("--json", action="store_true") | |
| args = parser.parse_args(argv) | |
| result = configure_vercel_worker( | |
| args.worker_url, | |
| site_url=args.site_url, | |
| code=args.code, | |
| environment=args.environment, | |
| redeploy=not args.no_redeploy, | |
| verify=args.verify, | |
| timeout=args.timeout, | |
| ) | |
| if args.json: | |
| print(json.dumps(result, indent=2)) | |
| else: | |
| print(f"Configured WORKER_BASE_URL={result['workerUrl']}") | |
| if result["redeployed"]: | |
| print("Redeployed Vercel production.") | |
| print("Next:") | |
| print(result["nextCommand"]) | |
| site_checks = result.get("siteChecks") | |
| if site_checks is not None and not all(check["ok"] for check in site_checks): | |
| return 1 | |
| return 0 | |
| def main() -> int: | |
| return main_with_args() | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |