File size: 2,933 Bytes
a6951f2
 
0131931
 
03fcfc5
 
3ec1b36
 
0131931
 
 
 
a6951f2
 
 
 
 
03fcfc5
a6951f2
03fcfc5
 
 
 
 
a6951f2
03fcfc5
 
 
 
 
 
 
0131931
 
 
 
 
a6951f2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
"""Start the PanGramGraph Space: fetch the data if the Space does not carry them, then serve.

The data (pgb/*, about 670 MB, and 80 MB more for influence) either sit in the Space itself, or in a
dataset repository named by the variable PGG_DATA_REPO; a private one is read with HF_TOKEN, a Space secret.
DATA are needed to start; INFLUENCE (the Coupled regions tab's knockout of one element,
serve_live /influence) are not: without them the Space starts and /health says influence is off.
HF_TOKEN also lets the Findings tab's reading of a window be written by an LLM (pg_reading, Hugging
Face Inference Providers): the token must be allowed to "Make calls to Inference Providers"; without
it the readings shipped in pgb/readings/ are still served and /health says new ones are off.
Where new readings and the day's counters are kept: READING_CACHE if set; else /data/readings when the
Space has persistent storage (/data, writable), so they survive a restart; else pgb/readings/ in the
container, lost at each restart (the shipped readings are always read from pgb/readings/).
"""
import os, sys
DATA = ["pgb/window.json", "pgb/window_emb.npy", "pgb/model_calls.npz", "pgb/graph_pgb.json", "pgb/fam_info.json",
        "pgb/chrom.npz", "pgb/chrom_genomes.json", "pgb/calls_top15_f.i32", "pgb/calls_top15_p.f16",
        "pgb/calls_ent.f16", "pgb/chrom_emb.f16"]
INFLUENCE = ["pgb/region_sets.json", "pgb/region_sets_close.json", "pgb/knock/decoder_halves.npz"]   # + the units caches, pgb/knock/units_cache_*.pkl
missing = [p for p in DATA if not os.path.exists(p)]
optional = [p for p in INFLUENCE if not os.path.exists(p)]
repo = os.environ.get("PGG_DATA_REPO")
if missing and not repo:
    sys.exit(f"missing data ({', '.join(missing[:3])}...) and no PGG_DATA_REPO to fetch them from")
if (missing or optional) and repo:
    from huggingface_hub import snapshot_download
    print(f"fetching {len(missing + optional)} data files from {repo}", flush=True)
    snapshot_download(repo_id=repo, repo_type="dataset", local_dir=".", token=os.environ.get("HF_TOKEN"),
                      allow_patterns=missing + optional + (["pgb/knock/units_cache_*.pkl"] if optional else []))
    missing = [p for p in DATA if not os.path.exists(p)]
    if missing: sys.exit(f"still missing after fetching from {repo}: {', '.join(missing)}")
optional = [p for p in INFLUENCE if not os.path.exists(p)]
if optional: print(f"influence off (missing {', '.join(optional)}): the rest of the page is served", flush=True)
if not os.environ.get("READING_CACHE") and os.path.isdir("/data") and os.access("/data", os.W_OK):
    try:
        os.makedirs("/data/readings", exist_ok=True); os.environ["READING_CACHE"] = "/data/readings"
    except OSError: pass
print(f"new readings kept in {os.environ.get('READING_CACHE') or 'pgb/readings (lost at a restart: no persistent storage)'}", flush=True)
os.execvp(sys.executable, [sys.executable, "serve_live.py"])