| """JamAI long-track rating app -- Hugging Face Space entrypoint. |
| |
| Wraps s04_longtrack_rating_app.py (copied verbatim into the Space repo, |
| next to this file, with longtrack_pool/ beside it -- s04 resolves both |
| relative to its own location, so no path surgery is needed). |
| |
| What this wrapper adds, and why: |
| 1. RATINGS PERSISTENCE. Space containers have EPHEMERAL filesystems -- |
| anything written locally is wiped on restart. A background |
| CommitScheduler pushes logs/ to a PRIVATE HF dataset repo every 2 |
| minutes. Each server boot writes its own uniquely-named CSV |
| (longtrack_ratings_<bootid>.csv): CommitScheduler mirrors folder |
| state, so reusing one filename would let a fresh boot's empty file |
| OVERWRITE history in the dataset -- unique-per-boot files only ever |
| ADD. Analysis concatenates logs/*.csv from the dataset repo. |
| 2. LOCKED WRITES. CSV appends take scheduler.lock so a commit never |
| snapshots a half-written row. |
| 3. Plain launch() -- Spaces serves the app directly; no share tunnel, |
| no relay, stable URL. |
| |
| Space setup (one-time, ~10 min -- see README.md for details): |
| - Create the Space (SDK: Gradio), upload this folder's files + |
| s04_longtrack_rating_app.py + longtrack_pool/. |
| - Space settings -> Secrets: HF_TOKEN = a WRITE-scoped token. |
| - Optionally set RATINGS_DATASET (else edit the default below). |
| Without HF_TOKEN the app still runs but ratings are NOT persisted -- |
| it prints a loud warning (fine for a quick look, never for real raters). |
| """ |
|
|
| import os |
| import sys |
| import uuid |
| from pathlib import Path |
|
|
| try: |
| import spaces |
| @spaces.GPU |
| def _dummy_gpu(): |
| pass |
| except ImportError: |
| pass |
|
|
| HERE = Path(__file__).resolve().parent |
| |
| |
| for _p in (HERE, HERE.parent): |
| if str(_p) not in sys.path: |
| sys.path.insert(0, str(_p)) |
|
|
| import s04_longtrack_rating_app as core |
|
|
| |
| |
| |
| |
| BOOT_ID = uuid.uuid4().hex[:8] |
| core.RATINGS_CSV = core.LOG_DIR / f"longtrack_ratings_{BOOT_ID}.csv" |
| core.LOG_DIR.mkdir(parents=True, exist_ok=True) |
|
|
| |
| |
| |
| scheduler = None |
| if os.environ.get("SPACE_ID") and os.environ.get("HF_TOKEN"): |
| try: |
| from huggingface_hub import CommitScheduler, HfApi |
| DATASET_ID = os.environ.get("RATINGS_DATASET") or ( |
| HfApi(token=os.environ["HF_TOKEN"]).whoami()["name"] |
| + "/jamai-longtrack-ratings") |
| scheduler = CommitScheduler( |
| repo_id=DATASET_ID, repo_type="dataset", private=True, |
| folder_path=str(core.LOG_DIR), path_in_repo="logs", |
| every=2, token=os.environ["HF_TOKEN"], |
| ) |
| _orig_append = core.append_log |
|
|
| def _locked_append(row, csv_path=None): |
| with scheduler.lock: |
| _orig_append(row, csv_path) |
|
|
| core.append_log = _locked_append |
| print(f"ratings persist to dataset {DATASET_ID} " |
| f"(file logs/longtrack_ratings_{BOOT_ID}.csv, every 2 min)") |
| except Exception as e: |
| scheduler = None |
| print(f"persistence setup FAILED ({e}) -- running WITHOUT it") |
| if scheduler is None: |
| print("=" * 70) |
| print("WARNING: ratings will NOT survive a restart (no persistence " |
| "active). On the Space, set the HF_TOKEN secret (write scope) " |
| "and check RATINGS_DATASET before real raters use this.") |
| print("=" * 70) |
|
|
| tracks = core.load_tracks() |
| print(f"loaded {len(tracks)} tracks") |
| demo = core.build_demo(tracks) |
| demo.launch(share=True, ssr_mode=False) |
|
|