CoolFace
Apppublic

gl29/kervent-projections

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
data.py187 linesDownload Raw Back to root
1import json2import os3 4from huggingface_hub import hf_hub_download, list_repo_files, upload_file5import streamlit as st6 7TOKEN = os.environ.get("HF_TOKEN")8REPO_ID = os.environ.get("DATASET_ID")9DEFAULT_FILENAME = "defaults.json"10 11 12def _profile_filename(name: str) -> str:13    if name == "Default":14        return DEFAULT_FILENAME15    slug = name.strip().lower().replace(" ", "_")16    return f"profile_{slug}.json"17 18 19def list_profiles() -> list[str]:20    """Discover available profiles from HF dataset (or local fallback)."""21    profiles = ["Default"]22    try:23        files = list_repo_files(REPO_ID, repo_type="dataset", token=TOKEN)24        for f in sorted(files):25            if f.startswith("profile_") and f.endswith(".json"):26                display = f[8:-5].replace("_", " ").title()27                profiles.append(display)28    except Exception:29        for f in sorted(os.listdir(".")):30            if f.startswith("profile_") and f.endswith(".json"):31                display = f[8:-5].replace("_", " ").title()32                profiles.append(display)33    return profiles34 35 36def _load_bundled_defaults() -> dict:37    """Load the defaults.json shipped with the app (the schema source of truth)."""38    if os.path.exists(DEFAULT_FILENAME):39        with open(DEFAULT_FILENAME, "r") as f:40            return json.load(f)41    return {}42 43 44def load_profile(name: str) -> dict:45    """Load a profile by display name. Falls back to local file.46 47    When loading the Default profile, any top-level keys present in the48    bundled defaults.json but missing from the stored copy are back-filled.49    This keeps the app working after schema changes even if the HF dataset50    still has an older format.51    """52    filename = _profile_filename(name)53    result = None54    try:55        path = hf_hub_download(56            repo_id=REPO_ID,57            filename=filename,58            repo_type="dataset",59            token=TOKEN,60        )61        with open(path, "r") as f:62            result = json.load(f)63    except Exception:64        if os.path.exists(filename):65            with open(filename, "r") as f:66                result = json.load(f)67        elif filename != DEFAULT_FILENAME and os.path.exists(DEFAULT_FILENAME):68            with open(DEFAULT_FILENAME, "r") as f:69                result = json.load(f)70 71    if result is None:72        result = _load_bundled_defaults()73 74    # Back-fill missing sections from the bundled defaults so that an older75    # saved profile doesn't hide newly-added config sections.  We go two76    # levels deep so that e.g. global.global_debt is filled even when the77    # stored data already has a "global" key from an older schema.78    bundled = _load_bundled_defaults()79    for key, default_val in bundled.items():80        if key not in result:81            result[key] = default_val82        elif isinstance(default_val, dict) and isinstance(result[key], dict):83            for sub_key, sub_val in default_val.items():84                if sub_key not in result[key]:85                    result[key][sub_key] = sub_val86 87    return result88 89 90def save_profile(name: str, data: dict):91    """Save a profile to HF dataset (and locally)."""92    filename = _profile_filename(name)93    json_str = json.dumps(data, indent=4)94    with open(filename, "w") as f:95        f.write(json_str)96    try:97        upload_file(98            path_or_fileobj=filename,99            path_in_repo=filename,100            repo_id=REPO_ID,101            repo_type="dataset",102            token=TOKEN,103        )104        st.success(f"โœ… Profile **{name}** saved permanently!")105    except Exception as e:106        st.warning(f"Saved locally but HF upload failed: {e}")107 108 109def delete_profile(name: str):110    """Delete a non-default profile from HF dataset and locally."""111    if name == "Default":112        return113    filename = _profile_filename(name)114    if os.path.exists(filename):115        os.remove(filename)116    try:117        from huggingface_hub import delete_file118        delete_file(119            path_in_repo=filename,120            repo_id=REPO_ID,121            repo_type="dataset",122            token=TOKEN,123        )124        st.success(f"๐Ÿ—‘๏ธ Profile **{name}** deleted.")125    except Exception as e:126        st.warning(f"Local delete OK but HF delete failed: {e}")127 128 129# ============================================================130# Research Tasks persistence131# ============================================================132 133RESEARCH_TASKS_FILENAME = "research_tasks.json"134RESEARCH_TASKS_BUNDLED = "research_tasks_default.json"135 136 137def load_research_tasks() -> dict:138    """Load the interactive research tracker from HF dataset, falling back to the bundled seed."""139    try:140        path = hf_hub_download(141            repo_id=REPO_ID,142            filename=RESEARCH_TASKS_FILENAME,143            repo_type="dataset",144            token=TOKEN,145        )146        with open(path, "r") as f:147            return json.load(f)148    except Exception:149        pass150 151    if os.path.exists(RESEARCH_TASKS_FILENAME):152        with open(RESEARCH_TASKS_FILENAME, "r") as f:153            return json.load(f)154 155    if os.path.exists(RESEARCH_TASKS_BUNDLED):156        with open(RESEARCH_TASKS_BUNDLED, "r") as f:157            return json.load(f)158 159    return {"sections": []}160 161 162def save_research_tasks(data: dict):163    """Save the research tracker state to HF dataset (and locally)."""164    json_str = json.dumps(data, indent=4)165    with open(RESEARCH_TASKS_FILENAME, "w") as f:166        f.write(json_str)167    try:168        upload_file(169            path_or_fileobj=RESEARCH_TASKS_FILENAME,170            path_in_repo=RESEARCH_TASKS_FILENAME,171            repo_id=REPO_ID,172            repo_type="dataset",173            token=TOKEN,174        )175        st.success("Research tracker saved!")176    except Exception as e:177        st.warning(f"Saved locally but HF upload failed: {e}")178 179 180# Backward-compatible aliases181def load_from_persistence() -> dict:182    return load_profile("Default")183 184 185def save_to_persistence(data: dict):186    save_profile("Default", data)187