from __future__ import annotations import os from pathlib import Path import requests from huggingface_hub import HfApi ROOT = Path(__file__).resolve().parents[1] REPO_ID = os.getenv("MAFIA_HF_SPACE_REPO", "build-small-hackathon/mafia") PRIVATE = os.getenv("MAFIA_HF_SPACE_PRIVATE", "0").lower() in {"1", "true", "yes"} IGNORE_PATTERNS = [ ".git/*", ".pytest_cache/*", ".ruff_cache/*", "**/__pycache__/*", "**/.DS_Store", "reports/*", "research/*", "docs/*", "modal/*", "frontend/node_modules/*", "frontend/.vite/*", "frontend/coverage/*", "frontend/docs/*", "frontend/reports/*", "frontend/agent-test/*", "*.pyc", ] def main() -> None: token = os.environ.get("HF_TOKEN") or os.environ.get("HF_API_KEY") if not token: raise RuntimeError("Set HF_TOKEN or HF_API_KEY before deploying the Space.") api = HfApi(token=token) api.create_repo( repo_id=REPO_ID, repo_type="space", space_sdk="gradio", private=PRIVATE, exist_ok=True, space_secrets=[{"key": "HF_TOKEN", "value": token}], space_variables=[ {"key": "MAFIA_MODEL_BACKEND", "value": "zerogpu"}, {"key": "MAFIA_SESSION_BACKEND", "value": "memory"}, {"key": "MAFIA_ENABLE_GRADIO_MCP", "value": "0"}, {"key": "MAFIA_ZEROGPU_DURATION", "value": "180"}, ], ) api.add_space_secret(REPO_ID, "HF_TOKEN", token) api.add_space_variable(REPO_ID, "MAFIA_MODEL_BACKEND", "zerogpu") api.add_space_variable(REPO_ID, "MAFIA_SESSION_BACKEND", "memory") api.add_space_variable(REPO_ID, "MAFIA_ENABLE_GRADIO_MCP", "0") api.add_space_variable(REPO_ID, "MAFIA_ZEROGPU_DURATION", "180") # Runtime GPU size remains the docs default `large` because the provider # uses `@spaces.GPU(duration=...)` without requesting `xlarge`. api.request_space_hardware(REPO_ID, _zerogpu_hardware_slug(), sleep_time=172800) api.upload_folder( repo_id=REPO_ID, repo_type="space", folder_path=str(ROOT), commit_message="Migrate Mafia game to ZeroGPU Gradio Space", ignore_patterns=IGNORE_PATTERNS, ) visibility = "private" if PRIVATE else "public" print(f"Uploaded {visibility} Space: https://huggingface.co/spaces/{REPO_ID}") def _zerogpu_hardware_slug() -> str: response = requests.get("https://huggingface.co/api/spaces/hardware", timeout=20) response.raise_for_status() for item in response.json(): if item.get("prettyName") == "ZeroGPU": return str(item["name"]) raise RuntimeError("Hugging Face did not return a ZeroGPU hardware option.") if __name__ == "__main__": main()