| |
| """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() |
|
|