Spaces:
Sleeping
Sleeping
| """Hugging Face Space entry point. | |
| Runs `python app.py`. Pulls the private dataset (index/ + originals/) if | |
| STUDYHUB_DATASET is set, builds the StudyService, and launches the gated app. | |
| Secrets/config come from Space Secrets (environment variables): | |
| STUDYHUB_DATASET e.g. "your-user/studyhub-materials" (private dataset) | |
| HF_TOKEN read-only fine-grained token scoped to that dataset | |
| GROQ_API_KEY (+ optional CEREBRAS_API_KEY) | |
| APP_USERS "user:role:salt$hash, ..." (from `python -m studyhub.app.make_user`) | |
| STUDYHUB_EMBEDDER "bge-m3" (default) — must match the embedder used to build the index | |
| STUDYHUB_TITLE optional display title | |
| """ | |
| from __future__ import annotations | |
| import os | |
| from pathlib import Path | |
| def _maybe_pull_dataset() -> None: | |
| """Pull the private dataset and point the index/materials env vars at it. No-op locally.""" | |
| repo = os.getenv("STUDYHUB_DATASET") | |
| if not repo: | |
| return | |
| from huggingface_hub import snapshot_download | |
| local = snapshot_download( | |
| repo_id=repo, | |
| repo_type="dataset", | |
| token=os.getenv("HF_TOKEN"), | |
| local_dir=os.getenv("STUDYHUB_DATA_DIR", "data"), | |
| ) | |
| base = Path(local) | |
| os.environ.setdefault("STUDYHUB_INDEX_DIR", str(base / "index")) | |
| os.environ.setdefault("STUDYHUB_MATERIALS_DIR", str(base / "originals")) | |
| def build_demo(): | |
| _maybe_pull_dataset() | |
| from studyhub.app.auth import make_auth_fn, parse_users | |
| from studyhub.app.config import load_settings | |
| from studyhub.app.factory import build_service | |
| from studyhub.app.ui import build_app | |
| settings = load_settings() | |
| service = build_service(settings) | |
| users = parse_users(settings.app_users_raw) | |
| demo = build_app(service, title=settings.title) | |
| auth = make_auth_fn(users) if users else None | |
| return demo, auth | |
| def main() -> None: | |
| demo, auth = build_demo() | |
| # Bind to all interfaces on the Space's port, and disable Node SSR (it errors on Spaces). | |
| # auth gates the whole app; never use share=True (it would bypass the gate). | |
| demo.queue(max_size=16).launch( | |
| server_name="0.0.0.0", | |
| server_port=int(os.getenv("PORT", "7860")), | |
| auth=auth, | |
| ssr_mode=False, | |
| ) | |
| if __name__ == "__main__": | |
| main() | |