# ============================================================ # ๐Ÿ“„ ุงู„ู…ู„ู: app/assets.py # ๐ŸŽฏ ุงู„ุบุฑุถ: ุชู†ุฒูŠู„ ุงู„ู…ู„ูุงุช ุงู„ูƒุจูŠุฑุฉ ุชู„ู‚ุงุฆูŠู‹ุง ุนู†ุฏ ุงู„ู†ุดุฑ (Streamlit Cloud). # # ุงู„ู…ู„ูุงุช ุงู„ูƒุจูŠุฑุฉ (ุงู„ู†ู…ุงุฐุฌ ุงู„ู…ููƒู…ูŽู‘ู…ุฉ + ุงู„ู€ embeddings + ุงู„ุจูŠุงู†ุงุช) ู„ุง ุชูุฑูุน # ุนู„ู‰ GitHub (ุชุชุฌุงูˆุฒ ุญุฏ 1GB). ู†ุฎุฒู‘ู†ู‡ุง ููŠ ู…ุณุชูˆุฏุน Hugging Face Hub ุนุงู…ุŒ # ูˆุงู„ุชุทุจูŠู‚ ูŠู†ุฒู‘ู„ู‡ุง ุฃูˆู„ ุชุดุบูŠู„ ูู‚ุท ุฅู† ู„ู… ุชูƒู† ู…ูˆุฌูˆุฏุฉ ู…ุญู„ูŠู‹ุง. # # ุงุณู… ู…ุณุชูˆุฏุน Hugging Face ูŠูู‚ุฑุฃ ู…ู† ุงู„ุฃุณุฑุงุฑ: st.secrets["HF_DATA_REPO"] # (ู…ุซุงู„: "username/reverse-dictionary-assets"). ุงู„ู…ุณุชูˆุฏุน ุนุงู… ูู„ุง ูŠุญุชุงุฌ ุชูˆูƒู†. # # ู…ุญู„ูŠู‹ุง (ุงู„ู…ู„ูุงุช ู…ูˆุฌูˆุฏุฉ) ู„ุง ูŠุญุฏุซ ุฃูŠ ุชู†ุฒูŠู„ โ€” ุงู„ุฏุงู„ุฉ ุชุฑุฌุน ููˆุฑู‹ุง. # ============================================================ import os from pathlib import Path import streamlit as st import config # ู…ุง ุงู„ุฐูŠ ู†ูู†ุฒู‘ู„ู‡ (ุฃู†ู…ุงุท ุงู„ู…ุณุงุฑุงุช ุฏุงุฎู„ ู…ุณุชูˆุฏุน HF): # - data/embeddings/ : ุงู„ู…ุชุฌู‡ุงุช ุงู„ู…ุญููˆุธุฉ (.npy) # - data/processed/ : ุงู„ุจูŠุงู†ุงุช ุงู„ู…ู†ุธู‘ูุฉ (data.csv) # - models/** : ูƒู„ ุงู„ู†ู…ุงุฐุฌ ุงู„ู…ุญู„ูŠุฉ (ุงู„ุซุงู„ุซ ูˆุฃูŠ ู†ู…ูˆุฐุฌ ู…ุญู„ูŠ ุฅุถุงููŠ). # ุงู„ู†ู…ุงุฐุฌ ู…ู† HuggingFace (ุงู„ุฃูˆู„/ุงู„ุซุงู†ูŠ) ุชูู†ุฒูŽู‘ู„ ุชู„ู‚ุงุฆูŠู‹ุง. DOWNLOAD_PATTERNS = [ "data/embeddings/**", "data/processed/data.csv", "models/**", ] def _setting(key: str) -> str | None: """ูŠู‚ุฑุฃ ุฅุนุฏุงุฏู‹ุง ู…ู† ู…ุชุบูŠู‘ุฑุงุช ุงู„ุจูŠุฆุฉ ุฃูˆู„ู‹ุง (HF Spaces)ุŒ ุซู… ู…ู† st.secrets ูู‚ุท ุฅู† ูˆูุฌุฏ ู…ู„ู secrets.toml ูุนู„ู‹ุง โ€” ู„ุชูุงุฏูŠ ุชุญุฐูŠุฑ ยซNo secrets foundยป.""" val = os.getenv(key) if val: return val secret_paths = ( "/root/.streamlit/secrets.toml", "/app/.streamlit/secrets.toml", os.path.expanduser("~/.streamlit/secrets.toml"), ".streamlit/secrets.toml", ) if any(os.path.exists(p) for p in secret_paths): try: return st.secrets[key] except Exception: return None return None def _repo_id() -> str | None: """ุงุณู… ู…ุณุชูˆุฏุน HF ุงู„ุฐูŠ ูŠุญูˆูŠ ุงู„ู…ู„ูุงุช ุงู„ูƒุจูŠุฑุฉ.""" return _setting("HF_DATA_REPO") def assets_ready() -> bool: """ู‡ู„ ูƒู„ ุงู„ู…ู„ูุงุช ุงู„ูƒุจูŠุฑุฉ ู…ูˆุฌูˆุฏุฉ ู…ุญู„ูŠู‹ุงุŸ""" if not config.PROCESSED_DATA_PATH.exists(): return False for m in config.MODELS: # ู…ู„ู ุงู„ู€ embeddings ู…ุทู„ูˆุจ ู„ูƒู„ ู†ู…ูˆุฐุฌ if not config.embedding_path(m["key"]).exists(): return False # ุงู„ู†ู…ุงุฐุฌ ุงู„ู…ุญู„ูŠุฉ (ู…ุณุงุฑ ู…ุทู„ู‚) ู„ุงุฒู… ูŠูƒูˆู† ู…ุฌู„ุฏู‡ุง ู…ูˆุฌูˆุฏู‹ุง. # ู†ู…ุงุฐุฌ HuggingFace (ู…ุซู„ "org/name") ุชูู†ุฒูŽู‘ู„ ุชู„ู‚ุงุฆูŠู‹ุง ูู„ุง ู†ูุญุตู‡ุง. if os.path.isabs(m["hf_id"]) and not Path(m["hf_id"]).exists(): return False return True def ensure_assets() -> None: """ูŠูู†ุฒู‘ู„ ุงู„ู…ู„ูุงุช ุงู„ูƒุจูŠุฑุฉ ู…ู† Hugging Face Hub ุฅู† ู„ู… ุชูƒู† ู…ูˆุฌูˆุฏุฉ.""" if assets_ready(): return repo = _repo_id() if not repo: raise RuntimeError( "ุงู„ู…ู„ูุงุช ุงู„ูƒุจูŠุฑุฉ (ุงู„ู†ู…ุงุฐุฌ/ุงู„ู€ embeddings) ุบูŠุฑ ู…ูˆุฌูˆุฏุฉุŒ ูˆ HF_DATA_REPO " "ุบูŠุฑ ู…ุถุจูˆุท ููŠ ุงู„ุฃุณุฑุงุฑ. ุฑุงุฌุน DEPLOY.md." ) from huggingface_hub import snapshot_download # ุชูู†ุฒูŽู‘ู„ ู…ุจุงุดุฑุฉ ุฅู„ู‰ ุฌุฐุฑ ุงู„ู…ุดุฑูˆุน ุจู†ูุณ ุงู„ุจู†ูŠุฉ (data/ุŒ models/...) snapshot_download( repo_id=repo, repo_type="model", local_dir=str(config.BASE_DIR), allow_patterns=DOWNLOAD_PATTERNS, )