#!/usr/bin/env python3 """Create/update a Docker Hugging Face Space for GitRag.""" from __future__ import annotations import argparse import os from pathlib import Path from huggingface_hub import HfApi, upload_folder from huggingface_hub.errors import HfHubHTTPError REPO_ROOT = Path(__file__).resolve().parents[2] def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="Deploy GitRag to a Hugging Face Space.") parser.add_argument("--space-id", required=True, help="Space id in the form /.") parser.add_argument( "--token", default=os.getenv("HF_API_KEY") or os.getenv("HF_TOKEN"), help="HF token. Defaults to HF_API_KEY (or HF_TOKEN) env var.", ) parser.add_argument( "--db-url", default=os.getenv("TURSO_DATABASE_URL") or os.getenv("DATABASE_URL"), help="Turso/libSQL URL; stored as TURSO_DATABASE_URL secret.", ) parser.add_argument( "--db-token", default=os.getenv("TURSO_AUTH_TOKEN") or os.getenv("DB_AUTH_TOKEN"), help="Turso auth token; stored as TURSO_AUTH_TOKEN secret.", ) parser.add_argument("--private", action="store_true", help="Create the space as private.") parser.add_argument( "--skip-upload", action="store_true", help="Only create/update metadata and secrets; do not upload code.", ) return parser.parse_args() def ensure_space(api: HfApi, space_id: str, private: bool) -> None: try: api.create_repo(repo_id=space_id, repo_type="space", space_sdk="docker", private=private, exist_ok=True) except HfHubHTTPError as exc: raise SystemExit(f"Failed to create/open space '{space_id}': {exc}") from exc def upsert_secret(api: HfApi, space_id: str, key: str, value: str | None) -> None: if not value: return api.add_space_secret(repo_id=space_id, key=key, value=value) def upload_source(space_id: str, token: str) -> None: ignore_patterns = [ ".git/*", ".venv/*", "**/__pycache__/*", "**/*.pyc", "*.egg-info/*", ] upload_folder( repo_id=space_id, repo_type="space", folder_path=str(REPO_ROOT), path_in_repo=".", token=token, ignore_patterns=ignore_patterns, commit_message="Deploy GitRag space", ) def main() -> None: args = parse_args() if not args.token: raise SystemExit("Missing token. Pass --token or set HF_API_KEY (or HF_TOKEN).") api = HfApi(token=args.token) ensure_space(api, args.space_id, args.private) upsert_secret(api, args.space_id, "TURSO_DATABASE_URL", args.db_url) upsert_secret(api, args.space_id, "TURSO_AUTH_TOKEN", args.db_token) if not args.skip_upload: upload_source(args.space_id, args.token) print(f"Space is ready: https://huggingface.co/spaces/{args.space_id}") if __name__ == "__main__": main()