roam / scripts /deploy_space.py
AarnavNoble's picture
Deploy from GitHub main
4cfd686 verified
Raw History Blame Contribute Delete
2.52 kB
"""
Deploy the current checkout to the Hugging Face Space.
The Space is updated by uploading files through the Hub API (that is how it
was deployed before; it does not share git history with GitHub). The Space
rebuilds its Docker image on every upload.
Run from the repo root, on main, with a clean working tree:
python scripts/deploy_space.py # upload code only
python scripts/deploy_space.py --set-secret # also create JWT_SECRET (first deploy only)
The server refuses to start without JWT_SECRET, so the first deploy of this
version needs --set-secret. Running it again later rotates the secret, which
signs every user out. HF_TOKEN is read from backend/.env.
Nothing is deleted from the Space. Files from older deploys that no longer
exist here stay behind unused.
"""
import argparse
import os
import secrets
from pathlib import Path
from dotenv import load_dotenv
from huggingface_hub import HfApi
REPO = "AarnavNoble/roam"
ROOT = Path(__file__).resolve().parents[1]
# Never upload local state, secrets, or the mobile app (the Space only serves the API).
IGNORE = [
".git/**", ".venv/**", "mobile/**", "data/**", "node_modules/**", ".claude/**",
"**/__pycache__/**", "*.pyc", ".pytest_cache/**", "**/.env", ".env*", "**/.DS_Store", ".DS_Store",
]
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--set-secret", action="store_true",
help="create a random JWT_SECRET on the Space (rotates it if one exists)")
args = parser.parse_args()
load_dotenv(ROOT / "backend" / ".env")
token = os.environ.get("HF_TOKEN", "").strip()
if not token:
raise SystemExit("HF_TOKEN is not set in backend/.env")
api = HfApi(token=token)
if args.set_secret:
api.add_space_secret(REPO, "JWT_SECRET", secrets.token_urlsafe(48))
print("JWT_SECRET set on the Space (value not shown)")
commit = api.upload_folder(
repo_id=REPO, repo_type="space", folder_path=str(ROOT),
commit_message="Deploy from GitHub main", ignore_patterns=IGNORE,
)
print(f"Uploaded: {commit.commit_url}")
files = api.list_repo_files(REPO, repo_type="space")
leaked = [f for f in files if f.endswith(".env")]
if leaked:
raise SystemExit(f"STOP: env files are on the Space, remove them and rotate keys: {leaked}")
print(f"{len(files)} files on the Space. It is rebuilding now:")
print(f" https://huggingface.co/spaces/{REPO}")
if __name__ == "__main__":
main()