Download ui/bootstrap.py from SolarWine/api: direct link, hf CLI and curl.
- Browser
- Download file 4.6 kB
-
https://huggingface.co/spaces/SolarWine/api/resolve/main/ui/bootstrap.py
- Command line
-
hf download hf://spaces/SolarWine/api/ui/bootstrap.py
-
curl -L -o bootstrap.py https://huggingface.co/spaces/SolarWine/api/resolve/main/ui/bootstrap.py
4.6 kB
| """ | |
| Shared bootstrap helpers for the SolarWine Streamlit app. | |
| Cached data loaders, AI/IMS health checks, and common utilities. | |
| """ | |
| from __future__ import annotations | |
| import base64 | |
| import threading | |
| import streamlit as st | |
| _BRAND_GREEN = "#00BD3E" | |
| _BRAND_DARK = "#1A1A1A" | |
| try: | |
| import plotly.express | |
| import plotly.graph_objects | |
| from plotly.subplots import make_subplots | |
| _HAS_PLOTLY = True | |
| except ImportError: | |
| _HAS_PLOTLY = False | |
| from pathlib import Path | |
| import pandas as pd | |
| # Threading state for IMS background refresh (shared with app.py via module-level vars) | |
| _IMS_REFRESH_LOCK = threading.Lock() | |
| _IMS_REFRESH_STARTED = False | |
| _IMS_REFRESH_STATUS: dict = {"ok": None, "error": None, "running": False} | |
| def load_labels(path: str) -> pd.DataFrame: | |
| return pd.read_csv(path, index_col=0, parse_dates=True) | |
| def load_metrics(path: str) -> pd.DataFrame: | |
| return pd.read_csv(path) | |
| def _check_ai_health_impl() -> dict: | |
| """Actual Gemini ping; cached so we only run once.""" | |
| from src.genai_utils import get_genai_client | |
| try: | |
| client = get_genai_client() | |
| except Exception as exc: # noqa: BLE001 | |
| return {"ok": False, "error": f"client init failed: {exc}"} | |
| try: | |
| resp = client.models.generate_content( | |
| model="gemini-2.5-flash", | |
| contents="ping", | |
| ) | |
| text = getattr(resp, "text", "") or "" | |
| return {"ok": bool(text.strip()), "error": None} | |
| except Exception as exc: # noqa: BLE001 | |
| return {"ok": False, "error": f"generate_content failed: {exc}"} | |
| def _cached_ai_ping() -> dict: | |
| """Cached Gemini health check (used by check_ai_health with timeout).""" | |
| return _check_ai_health_impl() | |
| def check_ai_health(timeout_seconds: float = 1.5) -> dict: | |
| """ | |
| Lightweight startup validation that Gemini is reachable. | |
| Waits at most timeout_seconds so app load stays under ~5s. | |
| Returns a dict with: | |
| - ok: bool | |
| - error: str | None | |
| """ | |
| from concurrent.futures import ThreadPoolExecutor, TimeoutError as FuturesTimeoutError | |
| with ThreadPoolExecutor(max_workers=1) as pool: | |
| future = pool.submit(_cached_ai_ping) | |
| try: | |
| return future.result(timeout=timeout_seconds) | |
| except FuturesTimeoutError: | |
| return {"ok": False, "error": "Health check timed out. Try refreshing."} | |
| def _run_ims_refresh(days: int = 7) -> None: | |
| """Background worker to refresh IMS cache without blocking the UI.""" | |
| from datetime import date, timedelta | |
| from src.ims_client import IMSClient | |
| global _IMS_REFRESH_STATUS | |
| try: | |
| ims = IMSClient() | |
| except Exception as exc: # noqa: BLE001 | |
| _IMS_REFRESH_STATUS = { | |
| "ok": False, | |
| "error": f"IMS init failed: {exc}", | |
| "running": False, | |
| } | |
| return | |
| try: | |
| today = date.today() | |
| start = (today - timedelta(days=days)).strftime("%Y-%m-%d") | |
| end = today.strftime("%Y-%m-%d") | |
| df = ims.fetch_and_cache(start, end) | |
| if df.empty: | |
| _IMS_REFRESH_STATUS = { | |
| "ok": False, | |
| "error": "IMS returned no data for the requested range.", | |
| "running": False, | |
| } | |
| else: | |
| _IMS_REFRESH_STATUS = {"ok": True, "error": None, "running": False} | |
| except Exception as exc: # noqa: BLE001 | |
| _IMS_REFRESH_STATUS = { | |
| "ok": False, | |
| "error": f"IMS fetch_and_cache failed: {exc}", | |
| "running": False, | |
| } | |
| def ensure_ims_refresh_background(days: int = 7) -> dict: | |
| """ | |
| Kick off IMS cache refresh in a background thread if not already started. | |
| Returns the latest known status dict without blocking page load. | |
| """ | |
| global _IMS_REFRESH_STARTED, _IMS_REFRESH_STATUS | |
| with _IMS_REFRESH_LOCK: | |
| if not _IMS_REFRESH_STARTED: | |
| _IMS_REFRESH_STARTED = True | |
| _IMS_REFRESH_STATUS = {"ok": None, "error": None, "running": True} | |
| t = threading.Thread(target=_run_ims_refresh, args=(days,), daemon=True) | |
| t.start() | |
| return dict(_IMS_REFRESH_STATUS) | |
| def img_to_base64(path: Path) -> str: | |
| return base64.b64encode(path.read_bytes()).decode() | |
| def now_israel(): | |
| from datetime import datetime | |
| try: | |
| from zoneinfo import ZoneInfo | |
| tz = ZoneInfo("Asia/Jerusalem") | |
| except ImportError: | |
| import datetime as _dt | |
| tz = _dt.timezone(_dt.timedelta(hours=2)) # fallback UTC+2 | |
| return datetime.now(tz) | |