import asyncio from contextlib import asynccontextmanager from fastapi import FastAPI from app.loader import load_services from app.store import all, get, history, init_db from app.scheduler import run_service from app.utils.schema import load_schema, render_response services = load_services() TASKS = [] @asynccontextmanager async def lifespan(app: FastAPI): # ===== STARTUP ===== init_db() for svc in services: task = asyncio.create_task(run_service(svc)) TASKS.append(task) yield # 👉 App chạy ở đây # ===== SHUTDOWN ===== for task in TASKS: task.cancel() app = FastAPI( title="Health Agent", lifespan=lifespan ) @app.get("/health") def health(): health_schema = load_schema("health_response") services = [] for name, data in all().items(): checks = data.get("checks", []) failed = sum(1 for c in checks if not c.get("ok")) services.append({ "message": f"Service {name} is {data.get('status')}", "name": name, "status": data.get("status") == "HEALTHY", "total_checks": len(checks), "failed_checks": failed, "last_updated": data.get("last_updated"), }) print(services) return render_response(health_schema, services) @app.get("/services") def services_list(): return all() @app.get("/services/{name}") def service_detail(name: str): return get(name) @app.get("/services/{name}/history") def service_history(name: str, limit: int = 20): return history(name, limit)