Spaces:
Running
Running
Perf: JSON-only API scaffolds (-21 components); warm chart imports on startup; aggregate walks/day on timeline
94fad59 verified | """End-to-end performance audit — every chart, every API, cold + warm. | |
| Goal: find anything that takes >5 seconds (Chiku's life depends on responsive | |
| tools during a medical event). | |
| Reports three tiers: | |
| FAIL > 5000 ms (unacceptable — must fix) | |
| WARN > 1500 ms (noticeable lag, optimize if possible) | |
| OK <= 1500 ms (responsive) | |
| Run: python -m scripts.perf_audit | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import logging | |
| import sys | |
| import time | |
| from pathlib import Path | |
| _ROOT = Path(__file__).resolve().parent.parent | |
| sys.path.insert(0, str(_ROOT)) | |
| from dotenv import load_dotenv | |
| load_dotenv(_ROOT / ".env") | |
| logging.basicConfig(level=logging.WARNING, format="%(levelname)s: %(message)s") | |
| CHIKU = "ec8ed3df-3b7b-4013-8d6d-c76832e1ec88" | |
| FAIL_MS = 5000 | |
| WARN_MS = 1500 | |
| class Row: | |
| __slots__ = ("label", "ms") | |
| def __init__(self, label: str, ms: float): | |
| self.label = label | |
| self.ms = ms | |
| def tier(self) -> str: | |
| if self.ms > FAIL_MS: | |
| return "FAIL" | |
| if self.ms > WARN_MS: | |
| return "WARN" | |
| return "OK " | |
| def timeit(label: str, fn) -> Row: | |
| t0 = time.perf_counter() | |
| fn() | |
| ms = (time.perf_counter() - t0) * 1000 | |
| return Row(label, ms) | |
| def audit_charts_cold() -> list[Row]: | |
| """Cold-start: time each chart in a fresh Python session by design. | |
| Call from a brand-new subprocess to measure realistic first-call cost. | |
| """ | |
| from guardiantails.services.hf_sync import download_backup | |
| from guardiantails.models import init_db, get_db | |
| download_backup() | |
| init_db() | |
| rows: list[Row] = [] | |
| # Import and run each chart from cold — measures full first-call cost | |
| # including any module chains loaded lazily | |
| from guardiantails.core.charts import ( | |
| dashboard_timeline, walk_distance_chart, weight_timeline, | |
| medication_adherence_trend, dose_status_calendar, | |
| seizure_severity_bar, seizure_by_hour_bar, seizure_triggers_pie, | |
| seizure_moon_polar, seizure_weather_chart, seizure_vs_pressure_scatter, | |
| poop_timing_bar, lab_trends_chart, cost_breakdown_pie, cost_cumulative_line, | |
| ) | |
| from guardiantails.core.dashboard_tab import _get_pet_photo_html | |
| CHART_FNS = [ | |
| ("dashboard_timeline 90d", lambda: dashboard_timeline(CHIKU, days=90)), | |
| ("walk_distance_chart 90d", lambda: walk_distance_chart(CHIKU, days=90)), | |
| ("weight_timeline 90d", lambda: weight_timeline(CHIKU, days=90)), | |
| ("medication_adherence", lambda: medication_adherence_trend(CHIKU)), | |
| ("dose_status_calendar", lambda: dose_status_calendar(CHIKU)), | |
| ("seizure_severity_bar", lambda: seizure_severity_bar(CHIKU)), | |
| ("seizure_by_hour_bar", lambda: seizure_by_hour_bar(CHIKU)), | |
| ("seizure_triggers_pie", lambda: seizure_triggers_pie(CHIKU)), | |
| ("seizure_moon_polar", lambda: seizure_moon_polar(CHIKU)), | |
| ("seizure_weather_chart", lambda: seizure_weather_chart(CHIKU)), | |
| ("seizure_vs_pressure", lambda: seizure_vs_pressure_scatter(CHIKU)), | |
| ("poop_timing_bar", lambda: poop_timing_bar(CHIKU)), | |
| ("lab_trends_chart", lambda: lab_trends_chart(CHIKU)), | |
| ("cost_breakdown_pie", lambda: cost_breakdown_pie(CHIKU)), | |
| ("cost_cumulative_line", lambda: cost_cumulative_line(CHIKU)), | |
| ("pet_photo_html", lambda: _get_pet_photo_html(CHIKU)), | |
| ] | |
| for label, fn in CHART_FNS: | |
| rows.append(timeit(label, fn)) | |
| return rows | |
| def audit_api_endpoints() -> list[Row]: | |
| """Hit the live Space's API endpoints, time each round-trip (cold once, | |
| warm twice), and report the WARM time (simulates steady-state usage). | |
| """ | |
| rows: list[Row] = [] | |
| try: | |
| from gradio_client import Client | |
| except Exception as e: | |
| rows.append(Row(f"gradio_client import failed: {e}", 999999)) | |
| return rows | |
| c = Client("kshitijthakkar/guardiantails", auth=("admin", "neoThakkar@2017")) | |
| endpoints = [ | |
| ("/v1/health", lambda: c.predict(api_name="/v1/health")), | |
| ("/v1/get_dashboard_stats", lambda: c.predict(CHIKU, api_name="/v1/get_dashboard_stats")), | |
| ("/v1/get_daily_log (recent)",lambda: c.predict(CHIKU, "2026-04-16", api_name="/v1/get_daily_log")), | |
| ("/v1/get_daily_log (old)", lambda: c.predict(CHIKU, "2025-12-20", api_name="/v1/get_daily_log")), | |
| ("/v1/get_seizures", lambda: c.predict(CHIKU, "10", "0", api_name="/v1/get_seizures")), | |
| ("/v1/get_weight_history", lambda: c.predict(CHIKU, api_name="/v1/get_weight_history")), | |
| ("/v1/get_emergency_packet", lambda: c.predict(CHIKU, api_name="/v1/get_emergency_packet")), | |
| ] | |
| for label, fn in endpoints: | |
| # First call = cold; time the second one (warm) so we report realistic steady-state | |
| try: | |
| fn() # warm the path | |
| except Exception as e: | |
| rows.append(Row(f"{label} (ERROR: {str(e)[:80]})", 999999)) | |
| continue | |
| rows.append(timeit(label, fn)) | |
| return rows | |
| def print_table(title: str, rows: list[Row]) -> None: | |
| print() | |
| print("=" * 70) | |
| print(title) | |
| print("=" * 70) | |
| print(f"{'TIER':6}{'MS':>8} LABEL") | |
| print("-" * 70) | |
| # Sort by ms desc to show worst first | |
| for r in sorted(rows, key=lambda r: -r.ms): | |
| print(f"{r.tier():6}{r.ms:7.0f} {r.label}") | |
| fails = [r for r in rows if r.ms > FAIL_MS] | |
| warns = [r for r in rows if WARN_MS < r.ms <= FAIL_MS] | |
| print() | |
| print(f" {len(fails)} FAIL | {len(warns)} WARN | {len(rows)-len(fails)-len(warns)} OK") | |
| def main() -> None: | |
| print("AUDIT: charts (local, cold-start)") | |
| chart_rows = audit_charts_cold() | |
| print_table("CHARTS — local cold-start", chart_rows) | |
| print() | |
| print("AUDIT: live Space API (warm — 2nd call)") | |
| api_rows = audit_api_endpoints() | |
| print_table("API — live Space round-trip (warm)", api_rows) | |
| if __name__ == "__main__": | |
| main() | |