Minifigures commited on
Commit
830d17d
·
verified ·
1 Parent(s): d5b27d2

fix: LFS pointer bootstrap (scripts/bootstrap_assets.py)

Browse files
Files changed (1) hide show
  1. scripts/bootstrap_assets.py +61 -0
scripts/bootstrap_assets.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Materialize git-LFS pointer files at container start (Hugging Face Spaces).
2
+
3
+ The Space build context delivers some binary files as LFS pointers rather than
4
+ real bytes (storage-class dependent and not under our control). Anything the
5
+ app needs at runtime — seed assets, model weights — is scanned here; pointer
6
+ files are replaced with the real content via the hub API, which resolves them
7
+ reliably. Local and compose runs have real files on disk, so this is a no-op.
8
+
9
+ Runs before the seeder in the image CMD chain.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import os
15
+ from pathlib import Path
16
+
17
+ POINTER_MAGIC = b"version https://git-lfs"
18
+ SCAN_DIRS = ("seed-assets", "weights")
19
+
20
+
21
+ def _pointer_files() -> list[Path]:
22
+ found: list[Path] = []
23
+ for scan in SCAN_DIRS:
24
+ root = Path(scan)
25
+ if not root.exists():
26
+ continue
27
+ for path in root.rglob("*"):
28
+ if path.is_file():
29
+ with path.open("rb") as fh:
30
+ if fh.read(len(POINTER_MAGIC)) == POINTER_MAGIC:
31
+ found.append(path)
32
+ return found
33
+
34
+
35
+ def main() -> None:
36
+ pointers = _pointer_files()
37
+ if not pointers:
38
+ print("[bootstrap] all binary assets are materialized; nothing to do", flush=True)
39
+ return
40
+
41
+ repo_id = os.environ.get("SPACE_ID") # injected by Spaces, e.g. "Minifigures/claimflow-api"
42
+ if repo_id is None:
43
+ raise SystemExit(
44
+ f"[bootstrap] {len(pointers)} LFS pointer files found but SPACE_ID is unset; "
45
+ f"cannot resolve: {[str(p) for p in pointers]}"
46
+ )
47
+
48
+ # The image pins offline mode for serving; this one bootstrap step needs the hub.
49
+ os.environ.pop("HF_HUB_OFFLINE", None)
50
+ os.environ.pop("TRANSFORMERS_OFFLINE", None)
51
+ from huggingface_hub import hf_hub_download
52
+
53
+ for path in pointers:
54
+ print(f"[bootstrap] resolving LFS pointer: {path}", flush=True)
55
+ resolved = hf_hub_download(repo_id=repo_id, repo_type="space", filename=str(path))
56
+ path.write_bytes(Path(resolved).read_bytes())
57
+ print(f"[bootstrap] materialized {len(pointers)} files", flush=True)
58
+
59
+
60
+ if __name__ == "__main__":
61
+ main()