Spaces:
Running
Running
File size: 3,115 Bytes
e317359 a9c5d6e e317359 a9c5d6e e317359 a9c5d6e e317359 a9c5d6e e317359 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | """Public UI and credential-free health report; operator files are not served."""
from __future__ import annotations
import json
from datetime import datetime, timezone
from pathlib import Path
import sys
import time
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
def health_report(root: Path = ROOT):
def read(path):
try:
return json.loads((root / path).read_text())
except (OSError, ValueError):
return {}
supervisor = read(".cloud-state/supervisor.json")
checkpoint = read(".cloud-state/checkpoint.json")
status = read("space/results/online_status.json")
publication = read("space/results/publication_status.json") or status
if status.get("push_status") == "failed":
publication = status
stamp = checkpoint.get("checkpointed_at")
def age_seconds(stamp):
try:
return (datetime.now(timezone.utc) - datetime.fromisoformat(stamp)).total_seconds()
except (ValueError, TypeError):
return None
age = age_seconds(stamp)
push_age = age_seconds(publication.get("pushed_at"))
failures = status.get("failed_forecasts", [])
model_failures = sum(item.get("model") != "*" for item in failures)
healthy = bool(supervisor.get("worker_running") and supervisor.get("evaluator_enabled")
and 0 <= time.time() - supervisor.get("updated_at", 0) < 90
and age is not None and 0 <= age < 3600
and status.get("aggregate_status") == "ok" and publication.get("push_status") == "ok"
and push_age is not None and 0 <= push_age < 3600 and model_failures == 0)
return {"ok": healthy, "source_revision": supervisor.get("source_revision"),
"evaluator_enabled": supervisor.get("evaluator_enabled", False),
"worker_running": supervisor.get("worker_running", False),
"checkpointed_at": stamp, "checkpoint_age_seconds": age,
"last_evaluation_at": status.get("finished_at"),
"evaluation_status": status.get("status"),
"model_failure_count": model_failures,
"unavailable_source_count": len(failures) - model_failures,
"pending_tasks": status.get("pending_tasks"),
"push_status": publication.get("push_status"), "pushed_at": publication.get("pushed_at")}
def main():
import gradio as gr
from fastapi import FastAPI
from fastapi.responses import JSONResponse
import uvicorn
from space.app import demo
app = FastAPI()
@app.get("/healthz")
def health():
report = health_report()
return JSONResponse(report, status_code=200 if report["ok"] else 503)
blocked = [str(ROOT / p) for p in ("space/results", "space/vendor/ts_bench/data",
".cloud-state", ".cache", ".env")]
app = gr.mount_gradio_app(app, demo.queue(default_concurrency_limit=20), path="/",
blocked_paths=[*blocked, "/proc"])
uvicorn.run(app, host="0.0.0.0", port=7860)
if __name__ == "__main__":
main()
|