annotation-studio / deploy.py
pepijn223's picture
pepijn223 HF Staff
Deploy cleaned hand annotation PR and verified minimal worker image
fdadf53 verified
Raw History Blame Contribute Delete
3.72 kB
"""Publish the Studio with a verified, committed LeRobot runtime bundle."""
import argparse
import hashlib
import json
import os
import subprocess
import sys
import tarfile
import tempfile
from pathlib import Path
from huggingface_hub import HfApi
def main():
"""Package committed code and publish the corresponding Studio catalog."""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--repo-id", default="finerobotics/annotation-studio")
parser.add_argument("--pipeline-ref", default="HEAD")
parser.add_argument("--package-only", action="store_true")
args = parser.parse_args()
folder = Path(__file__).resolve().parent
root = folder.parents[1]
if subprocess.check_output(["git", "diff", "HEAD", "--", "src", "pyproject.toml"], cwd=root):
raise RuntimeError("Commit or separately package tracked pipeline edits before publishing.")
commit = subprocess.check_output(["git", "rev-parse", args.pipeline_ref], cwd=root, text=True).strip()
archive = folder / "pipeline-source.tar.gz"
subprocess.run(
[
"git",
"archive",
"--format=tar.gz",
f"--output={archive}",
commit,
"src",
"pyproject.toml",
"LICENSE",
],
cwd=root,
check=True,
)
(folder / "pipeline-version.json").write_text(
json.dumps(
{
"git_commit": commit,
"sha256": hashlib.sha256(archive.read_bytes()).hexdigest(),
"preset": "abc_phases_schema_with_original_window_recovery",
"preset_date": "2026-09-25",
"engine": "lerobot.annotations.runtime",
"framework_pr": "https://github.com/huggingface/lerobot/pull/4892",
"human_video_pr": "https://github.com/huggingface/lerobot/pull/4809",
},
indent=2,
)
+ "\n"
)
with tempfile.TemporaryDirectory(prefix="studio-catalog-") as temporary:
with tarfile.open(archive) as source:
source.extractall(temporary, filter="data")
catalog = json.loads(
subprocess.check_output(
[
sys.executable,
"-c",
"import json; from hand_actions import public_catalog; print(json.dumps(public_catalog()))",
],
cwd=temporary,
env={
**os.environ,
"PYTHONPATH": os.pathsep.join([str(Path(temporary) / "src"), str(folder)]),
},
text=True,
)
)
catalog["lerobot_revision"] = commit
(folder / "hand-pipeline-catalog.json").write_text(json.dumps(catalog, indent=2) + "\n")
if args.package_only:
print(f"Packaged pipeline {commit}")
return
api = HfApi()
repo = args.repo_id
api.create_repo(repo, repo_type="space", space_sdk="docker", private=False, exist_ok=True)
result = api.upload_folder(
repo_id=repo,
repo_type="space",
folder_path=folder,
ignore_patterns=[
"__pycache__/**",
".pytest_cache/**",
".ruff_cache/**",
"*.pyc",
"frontend/node_modules/**",
"frontend/dist/**",
".cache/**",
".git/**",
],
delete_patterns=["app.py", "frontend/src/HandSetupView.tsx", "frontend/src/hands.css"],
commit_message="Use native EgoHand/SOMA hand actions with DROID-W and MoGe on HF Jobs",
)
print(f"https://huggingface.co/spaces/{repo}\nRevision: {result.oid}")
if __name__ == "__main__":
main()