"""Publish only application source to a Hugging Face Docker Space. Authentication uses an existing HF login or HF_TOKEN. No token is saved by this script. The dataset is never written to. No paid hardware is requested. """ from __future__ import annotations import argparse from pathlib import Path import sys from huggingface_hub import HfApi, get_token from huggingface_hub.errors import RepositoryNotFoundError def main() -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--repo-id", default="VAST-AI/Tripo-Simready-Explorer") parser.add_argument("--public", action="store_true", help="Create a public Space; new Spaces are private otherwise.") parser.add_argument("--update", action="store_true", help="Allow updating an existing Space without changing its visibility.") parser.add_argument("--check", action="store_true", help="Check files and authentication without remote writes.") args = parser.parse_args() root = Path(__file__).resolve().parent required = ["README.md", "Dockerfile", "requirements.txt", "backend/app.py", "frontend/package.json", "frontend/package-lock.json"] missing = [p for p in required if not (root / p).is_file()] if missing: parser.error("Missing application files: " + ", ".join(missing)) token = get_token() if not token: print("No Hugging Face login found. Run `hf auth login` in your terminal, then retry.", file=sys.stderr) return 2 api = HfApi(token=token) identity = api.whoami() print(f"Authenticated as {identity.get('name', '(unknown)')}; target Space: {args.repo_id}") exists = False try: info = api.space_info(args.repo_id) exists = True if not args.update: parser.error(f"Space {args.repo_id} already exists. Inspect it first; pass --update to publish a new app revision.") if getattr(info, "sdk", None) not in (None, "docker"): parser.error("Existing Space does not use the Docker SDK.") except RepositoryNotFoundError: pass if args.check: print("Application files and login checked. No remote changes made.") return 0 if not exists: api.create_repo(repo_id=args.repo_id, repo_type="space", space_sdk="docker", private=not args.public) # An explicit allow-list prevents local caches, tokens, test downloads, # node_modules and build output from being sent to the Hub. commit = api.upload_folder( repo_id=args.repo_id, repo_type="space", folder_path=root, allow_patterns=[ "README.md", "Dockerfile", "requirements.txt", ".dockerignore", "deploy.py", "scripts/smoke_test.py", "backend/*.py", "backend/**/*.py", "frontend/package.json", "frontend/package-lock.json", "frontend/index.html", "frontend/tsconfig*.json", "frontend/vite.config.*", "frontend/src/**", "frontend/public/**", ], ignore_patterns=["**/__pycache__/**", "**/.env*", "**/.DS_Store", "**/*.pyc"], commit_message="Build Tripo SimReady Explorer with live dataset and joint previews", ) print(f"Uploaded commit: {commit.oid}") print(f"Space: https://huggingface.co/spaces/{args.repo_id}") print("Hugging Face will build the Docker app. Check the Space build logs, then open the App tab.") return 0 if __name__ == "__main__": raise SystemExit(main())