#!/usr/bin/env python3 """Deploy the chat site: Modal backend + HuggingFace Space + secrets.""" import os import re import subprocess from dotenv import load_dotenv from huggingface_hub import HfApi, SpaceHardware load_dotenv() SPACE_TITLE = "posttraining-practice" def require_env(name: str) -> str: """Get required environment variable or exit with error.""" value = os.environ.get(name) if value is None: raise SystemExit(f"ERROR: {name} must be set in .env") return value def main(): api_key = require_env("MODEL_SITE_API_KEY") site_password = require_env("SITE_PASSWORD") api = HfApi() user = api.whoami()["name"] space_id = f"{user}/{SPACE_TITLE}" # Deploy Modal backend print("Deploying Modal backend...") result = subprocess.run( ["uv", "run", "modal", "deploy", "site/backend.py"], capture_output=True, text=True, ) print(result.stdout + result.stderr) match = re.search(r"https://[^\s]+\.modal\.run", result.stdout + result.stderr) if match is None: raise SystemExit("ERROR: Could not find Modal endpoint URL") modal_endpoint = match.group(0) # Generate requirements.txt result = subprocess.run( ["uv", "export", "--only-group", "site", "--no-hashes", "--no-dev"], capture_output=True, text=True, ) with open("site/requirements.txt", "w") as f: f.write(result.stdout) # Create/update HuggingFace Space print(f"Deploying to HuggingFace Space {space_id}...") api.create_repo( repo_id=space_id, repo_type="space", space_sdk="gradio", space_hardware=SpaceHardware.CPU_BASIC, exist_ok=True, ) api.upload_folder( folder_path="site", repo_id=space_id, repo_type="space", ) os.remove("site/requirements.txt") # Set secrets print("Setting secrets...") api.add_space_secret(repo_id=space_id, key="MODAL_ENDPOINT", value=modal_endpoint) api.add_space_secret(repo_id=space_id, key="MODEL_SITE_API_KEY", value=api_key) api.add_space_secret(repo_id=space_id, key="SITE_PASSWORD", value=site_password) print(f"Done! https://huggingface.co/spaces/{space_id}") if __name__ == "__main__": main()