from contextlib import asynccontextmanager from typing import Any from fastapi import FastAPI, HTTPException, Request from fastapi.middleware.cors import CORSMiddleware from .host_client import HostApiError, HostClient from .journey import build_journey from .models import JourneyView, RunSummary host = HostClient() @asynccontextmanager async def lifespan(_app: FastAPI): yield close = getattr(host, "aclose", None) if close is not None: await close() app = FastAPI(title="Script Build Journey", version="0.1.0", lifespan=lifespan) app.add_middleware( CORSMiddleware, allow_origins=["http://127.0.0.1:3008", "http://localhost:3008"], allow_credentials=True, allow_methods=["GET"], allow_headers=["*"], ) @app.get("/api/health") def health() -> dict[str, str]: return { "status": "ok", "service": "script-build-journey", } @app.get("/api/runs", response_model=list[RunSummary]) async def runs(request: Request) -> list[RunSummary]: payload = await _host_call(host.list_runs(request.headers)) return [ RunSummary( script_build_id=int(item["id"]), status=str(item.get("status") or "unknown"), summary=str(item.get("summary") or f"Script Build {item['id']}"), started_at=item.get("start_time"), completed_at=item.get("end_time"), ) for item in payload.get("items") or [] if isinstance(item, dict) and item.get("id") is not None ] @app.get("/api/runs/{script_build_id}/journey", response_model=JourneyView) async def journey(script_build_id: int, request: Request) -> JourneyView: source = await _host_call(host.journey_source(script_build_id, request.headers)) return build_journey(script_build_id, source) @app.get("/api/runs/{script_build_id}/artifacts/{artifact_version_id}") async def artifact( script_build_id: int, artifact_version_id: int, request: Request ) -> dict[str, Any]: return await _host_call(host.artifact(script_build_id, artifact_version_id, request.headers)) async def _host_call(awaitable: Any) -> dict[str, Any]: try: value = await awaitable except HostApiError as exc: raise HTTPException(status_code=exc.status_code, detail=str(exc)) from exc return value