#!/usr/bin/env python3 """Deploy PolyGuard to a Hugging Face Docker Space via HfApi. This path avoids the current OpenEnv CLI README metadata upload issue while still shipping the same OpenEnv/FastAPI runtime. """ from __future__ import annotations import argparse from pathlib import Path import shutil from huggingface_hub import HfApi ROOT = Path(__file__).resolve().parents[1] def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="Deploy PolyGuard OpenEnv Space with valid HF metadata.") parser.add_argument("--repo-id", default="TheJackBright/polyguard-openenv") parser.add_argument("--bundle-dir", default="/tmp/polyguard-openenv-space") parser.add_argument("--private", action="store_true") parser.add_argument("--skip-upload", action="store_true") return parser.parse_args() def _ignore(_dir: str, names: list[str]) -> set[str]: ignored = { ".git", ".venv", "__pycache__", ".pytest_cache", ".mypy_cache", ".ruff_cache", "outputs", "checkpoints", "polyguard_rl.egg-info", "dist", "build", } return { name for name in names if name in ignored or name.endswith(".pyc") or name == "node_modules" or name == ".DS_Store" } def build_bundle(bundle_dir: Path) -> None: if bundle_dir.exists(): shutil.rmtree(bundle_dir) shutil.copytree(ROOT, bundle_dir, ignore=_ignore) readme = bundle_dir / "README.md" project_readme = readme.read_text(encoding="utf-8") if readme.exists() else "# PolyGuard OpenEnv\n" readme.write_text( "\n".join( [ "---", "title: PolyGuard OpenEnv", "colorFrom: blue", "colorTo: green", "sdk: docker", "app_port: 8100", "pinned: false", "---", "", project_readme, ] ), encoding="utf-8", ) def main() -> None: args = parse_args() bundle_dir = Path(args.bundle_dir) build_bundle(bundle_dir) if args.skip_upload: print(f"bundle_dir={bundle_dir}") return api = HfApi() api.create_repo( repo_id=args.repo_id, repo_type="space", space_sdk="docker", private=args.private, exist_ok=True, ) api.upload_folder( repo_id=args.repo_id, repo_type="space", folder_path=str(bundle_dir), commit_message="Deploy PolyGuard OpenEnv Space", ignore_patterns=[ ".git/*", ".venv/*", "**/node_modules/*", "outputs/*", "checkpoints/*", "**/__pycache__/*", "*.pyc", ], ) print(f"space_url=https://huggingface.co/spaces/{args.repo_id}") print(f"runtime_url=https://{args.repo_id.replace('/', '-').lower()}.hf.space") print(f"bundle_dir={bundle_dir}") if __name__ == "__main__": main()