k22056537 commited on
Commit
f6f50c4
·
1 Parent(s): 5bbefab

fix: resolve LFS pointers at runtime instead of build time

Browse files

Build-time downloads fail (circular dep — files not served while
building). Moved LFS resolution to a startup script that runs
before uvicorn launches.

Files changed (3) hide show
  1. Dockerfile +2 -47
  2. resolve_lfs.py +46 -0
  3. start.sh +8 -0
Dockerfile CHANGED
@@ -21,58 +21,13 @@ RUN pip install --no-cache-dir -r requirements.txt
21
 
22
  COPY . .
23
 
24
- # HF Docker builds copy LFS pointers, not real files.
25
- # Resolve them by downloading from the HF API.
26
- ARG HF_SPACE=FocusGuard/final
27
- RUN python -c "\
28
- import os, urllib.request, sys;\
29
- SPACE='${HF_SPACE}';\
30
- BASE=f'https://huggingface.co/spaces/{SPACE}/resolve/main';\
31
- files=[\
32
- 'checkpoints/mlp_best.pt',\
33
- 'checkpoints/scaler_mlp.joblib',\
34
- 'checkpoints/hybrid_combiner.joblib',\
35
- 'checkpoints/hybrid_focus_config.json',\
36
- 'checkpoints/xgboost_face_orientation_best.json',\
37
- 'checkpoints/meta_best.npz',\
38
- 'checkpoints/meta_mlp.npz',\
39
- 'checkpoints/L2CSNet_gaze360.pkl',\
40
- 'models/L2CS-Net/models/L2CSNet_gaze360.pkl',\
41
- ];\
42
- for f in files:\
43
- path=f;\
44
- is_ptr=False;\
45
- if os.path.isfile(path):\
46
- with open(path,'rb') as fh:\
47
- is_ptr=fh.read(50).startswith(b'version https://git-lfs');\
48
- if not os.path.isfile(path) or is_ptr:\
49
- url=f'{BASE}/{f}';\
50
- print(f'Downloading {f} ...');\
51
- try:\
52
- os.makedirs(os.path.dirname(path),exist_ok=True);\
53
- urllib.request.urlretrieve(url,path);\
54
- sz=os.path.getsize(path);\
55
- print(f' OK ({sz} bytes)');\
56
- except Exception as e:\
57
- print(f' WARN: {e}');\
58
- else:\
59
- print(f'[OK] {f} ({os.path.getsize(path)} bytes)');\
60
- print('Checkpoint resolution done')\
61
- "
62
-
63
  RUN npm install && npm run build && mkdir -p /app/static && cp -R dist/* /app/static/
64
 
65
  ENV FOCUSGUARD_CACHE_DIR=/app/.cache/focusguard
66
- RUN python -c "\
67
- try:\
68
- from models.face_mesh import _ensure_model; _ensure_model(); print('face_mesh model cached')\
69
- except Exception as e:\
70
- print(f'face_mesh pre-download skipped: {e} — will retry at runtime')\
71
- "
72
 
73
- RUN mkdir -p /app/data && chown -R user:user /app
74
 
75
  USER user
76
  EXPOSE 7860
77
 
78
- CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860", "--log-level", "info"]
 
21
 
22
  COPY . .
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  RUN npm install && npm run build && mkdir -p /app/static && cp -R dist/* /app/static/
25
 
26
  ENV FOCUSGUARD_CACHE_DIR=/app/.cache/focusguard
 
 
 
 
 
 
27
 
28
+ RUN mkdir -p /app/data /app/.cache && chown -R user:user /app
29
 
30
  USER user
31
  EXPOSE 7860
32
 
33
+ CMD ["bash", "start.sh"]
resolve_lfs.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Resolve Git LFS pointers left by HF Docker builds."""
2
+ import os
3
+ import urllib.request
4
+
5
+ SPACE = os.environ.get("SPACE_ID", "FocusGuard/final")
6
+ BASE = f"https://huggingface.co/spaces/{SPACE}/resolve/main"
7
+
8
+ FILES = [
9
+ "checkpoints/mlp_best.pt",
10
+ "checkpoints/scaler_mlp.joblib",
11
+ "checkpoints/hybrid_combiner.joblib",
12
+ "checkpoints/hybrid_focus_config.json",
13
+ "checkpoints/xgboost_face_orientation_best.json",
14
+ "checkpoints/meta_best.npz",
15
+ "checkpoints/meta_mlp.npz",
16
+ "checkpoints/L2CSNet_gaze360.pkl",
17
+ "models/L2CS-Net/models/L2CSNet_gaze360.pkl",
18
+ ]
19
+
20
+
21
+ def _is_lfs_pointer(path):
22
+ if not os.path.isfile(path):
23
+ return True
24
+ with open(path, "rb") as f:
25
+ return f.read(50).startswith(b"version https://git-lfs")
26
+
27
+
28
+ def resolve():
29
+ for rel in FILES:
30
+ if not _is_lfs_pointer(rel):
31
+ sz = os.path.getsize(rel)
32
+ print(f"[OK] {rel} ({sz} bytes)")
33
+ continue
34
+ url = f"{BASE}/{rel}"
35
+ print(f"[LFS] Downloading {rel} ...")
36
+ try:
37
+ os.makedirs(os.path.dirname(rel), exist_ok=True)
38
+ urllib.request.urlretrieve(url, rel)
39
+ print(f" -> {os.path.getsize(rel)} bytes")
40
+ except Exception as e:
41
+ print(f" WARN: {e}")
42
+ print("LFS resolution done.")
43
+
44
+
45
+ if __name__ == "__main__":
46
+ resolve()
start.sh ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ echo "=== Resolving LFS pointers ==="
5
+ python resolve_lfs.py
6
+
7
+ echo "=== Starting FocusGuard ==="
8
+ exec uvicorn main:app --host 0.0.0.0 --port 7860 --log-level info