holy agent
This commit is contained in:
83
hpcsim/api.py
Normal file
83
hpcsim/api.py
Normal file
@@ -0,0 +1,83 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from fastapi import FastAPI, Body, HTTPException
|
||||
from fastapi.responses import JSONResponse
|
||||
from pydantic import BaseModel
|
||||
import httpx
|
||||
|
||||
from .enrichment import Enricher
|
||||
from .adapter import normalize_telemetry
|
||||
|
||||
app = FastAPI(title="HPCSim Enrichment API", version="0.1.0")
|
||||
|
||||
# Single Enricher instance keeps state across laps
|
||||
_enricher = Enricher()
|
||||
|
||||
# Simple in-memory store of recent enriched records
|
||||
_recent: List[Dict[str, Any]] = []
|
||||
_MAX_RECENT = 200
|
||||
|
||||
# Optional callback URL to forward enriched data to next stage
|
||||
_CALLBACK_URL = os.getenv("NEXT_STAGE_CALLBACK_URL")
|
||||
|
||||
|
||||
class EnrichedRecord(BaseModel):
|
||||
lap: int
|
||||
aero_efficiency: float
|
||||
tire_degradation_index: float
|
||||
ers_charge: float
|
||||
fuel_optimization_score: float
|
||||
driver_consistency: float
|
||||
weather_impact: str
|
||||
|
||||
|
||||
@app.post("/ingest/telemetry")
|
||||
async def ingest_telemetry(payload: Dict[str, Any] = Body(...)):
|
||||
"""Receive raw telemetry (from Pi), normalize, enrich, return enriched.
|
||||
|
||||
Optionally forwards to NEXT_STAGE_CALLBACK_URL if set.
|
||||
"""
|
||||
try:
|
||||
normalized = normalize_telemetry(payload)
|
||||
enriched = _enricher.enrich(normalized)
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=f"Failed to enrich: {e}")
|
||||
|
||||
_recent.append(enriched)
|
||||
if len(_recent) > _MAX_RECENT:
|
||||
del _recent[: len(_recent) - _MAX_RECENT]
|
||||
|
||||
# Async forward to next stage if configured
|
||||
if _CALLBACK_URL:
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=5.0) as client:
|
||||
await client.post(_CALLBACK_URL, json=enriched)
|
||||
except Exception:
|
||||
# Don't fail ingestion if forwarding fails; log could be added here
|
||||
pass
|
||||
|
||||
return JSONResponse(enriched)
|
||||
|
||||
|
||||
@app.post("/enriched")
|
||||
async def post_enriched(enriched: EnrichedRecord):
|
||||
"""Allow posting externally enriched records (bypass local computation)."""
|
||||
rec = enriched.model_dump()
|
||||
_recent.append(rec)
|
||||
if len(_recent) > _MAX_RECENT:
|
||||
del _recent[: len(_recent) - _MAX_RECENT]
|
||||
return JSONResponse(rec)
|
||||
|
||||
|
||||
@app.get("/enriched")
|
||||
async def list_enriched(limit: int = 50):
|
||||
limit = max(1, min(200, limit))
|
||||
return JSONResponse(_recent[-limit:])
|
||||
|
||||
|
||||
@app.get("/healthz")
|
||||
async def healthz():
|
||||
return {"status": "ok", "stored": len(_recent)}
|
||||
Reference in New Issue
Block a user