| |
| """ |
| Deploy CAPScore to a Hugging Face Docker Space. |
| |
| Usage: |
| HF_TOKEN=hf_xxx python deploy/deploy_hf.py [space_name] |
| |
| Requires: pip install huggingface_hub |
| Reads optional secrets from the environment (or .env) and sets them as Space |
| secrets: ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENAI_MODEL. |
| """ |
| from __future__ import annotations |
|
|
| import os |
| import sys |
| from pathlib import Path |
|
|
| from huggingface_hub import HfApi, add_space_secret, create_repo, upload_folder |
|
|
| REPO_ROOT = Path(__file__).resolve().parent.parent |
|
|
| SPACE_README = """--- |
| title: CAPScore Agent |
| emoji: 🛡️ |
| colorFrom: indigo |
| colorTo: purple |
| sdk: docker |
| app_port: 8000 |
| pinned: false |
| license: mit |
| --- |
| |
| # CAPScore Agent — Verifiable Due Diligence for the Agent Economy |
| |
| CROO Hackathon 2026. FastAPI serves both the dashboard (at `/`) and the REST API |
| (`/health`, `/jobs/...`). Submit a GitHub repo or agent listing and receive a |
| judging-aligned scorecard plus a verifiable proof pack (SHA-256 hash, manifest, |
| attestation, execution log). |
| """ |
|
|
| IGNORE = [ |
| ".git/*", ".git", ".venv/*", ".venv", "runs/*", "runs", |
| "node_modules/*", "**/node_modules/*", ".env", "*.pyc", "__pycache__/*", |
| "**/__pycache__/*", "*.egg-info/*", "**/*.egg-info/*", |
| ".pytest_cache/*", "**/.pytest_cache/*", ".build_trigger", |
| "cap-provider/dist/*", "cap-provider/package-lock.json", |
| ] |
|
|
|
|
| def _load_env_file() -> None: |
| env = REPO_ROOT / ".env" |
| if not env.exists(): |
| return |
| for line in env.read_text(encoding="utf-8").splitlines(): |
| line = line.strip() |
| if not line or line.startswith("#") or "=" not in line: |
| continue |
| k, v = line.split("=", 1) |
| os.environ.setdefault(k.strip(), v.strip()) |
|
|
|
|
| def main() -> int: |
| _load_env_file() |
| token = os.environ.get("HF_TOKEN") |
| if not token: |
| print("ERROR: HF_TOKEN not set (env or .env)", file=sys.stderr) |
| return 1 |
|
|
| space_name = sys.argv[1] if len(sys.argv) > 1 else "capscore-agent" |
|
|
| api = HfApi(token=token) |
| user = api.whoami()["name"] |
| repo_id = f"{user}/{space_name}" |
| print(f"[hf] deploying to Space: {repo_id}") |
|
|
| create_repo(repo_id, repo_type="space", space_sdk="docker", |
| token=token, exist_ok=True) |
|
|
| |
| readme = REPO_ROOT / "README.md" |
| original = readme.read_text(encoding="utf-8") if readme.exists() else "" |
| backup = None |
| try: |
| backup = original |
| readme.write_text(SPACE_README, encoding="utf-8") |
| upload_folder( |
| repo_id=repo_id, repo_type="space", folder_path=str(REPO_ROOT), |
| token=token, ignore_patterns=IGNORE, |
| commit_message="Deploy CAPScore single-container build", |
| ) |
| finally: |
| if backup is not None: |
| readme.write_text(backup, encoding="utf-8") |
|
|
| |
| for key in ("ANTHROPIC_API_KEY", "OPENAI_API_KEY", "OPENAI_MODEL", |
| "ANTHROPIC_MODEL"): |
| val = os.environ.get(key) |
| if val: |
| add_space_secret(repo_id, key, val, token=token) |
| print(f"[hf] set secret: {key}") |
|
|
| url = f"https://{user.replace('_', '-')}-{space_name}.hf.space" |
| print(f"[hf] done. Building... will be live at: {url}") |
| print(f"[hf] check: {url}/health") |
| return 0 |
|
|
|
|
| if __name__ == "__main__": |
| raise SystemExit(main()) |
|
|