Spaces:
Running
Running
| """REST API for the Decidron network simulator.""" | |
| from __future__ import annotations | |
| from fastapi import APIRouter, HTTPException | |
| from pydantic import BaseModel | |
| from app.decidron.engine import engine | |
| from app.decidron.diagrams import to_vis_network | |
| from app.decidron.models import ProcessingCommand, RunResult, SensorInput | |
| router = APIRouter(prefix="/decidron", tags=["decidron"]) | |
| def _network_payload() -> dict: | |
| nodes = engine.network.nodes_list() | |
| return { | |
| "version": engine.network.version, | |
| "nodes": [n.model_dump() for n in nodes], | |
| "edges": [e.model_dump(by_alias=True) for e in engine.network.edges], | |
| "diagram": to_vis_network(nodes, engine.network.edges), | |
| } | |
| async def get_network() -> dict: | |
| return _network_payload() | |
| async def submit_sensor_input(sensor_input: SensorInput) -> dict: | |
| engine.add_sensor_input(sensor_input) | |
| return { | |
| "queued": sensor_input.model_dump(), | |
| "pending_count": len(engine.pending_inputs), | |
| } | |
| async def list_commands() -> list[ProcessingCommand]: | |
| return engine.list_commands() | |
| async def create_command(command: ProcessingCommand) -> ProcessingCommand: | |
| return engine.add_command(command) | |
| async def delete_command(name: str) -> dict: | |
| if not engine.remove_command(name): | |
| raise HTTPException(status_code=404, detail=f"No command named '{name}'") | |
| return {"deleted": name} | |
| class RunRequest(BaseModel): | |
| inputs: list[SensorInput] | None = None | |
| async def run_simulation(req: RunRequest | None = None) -> dict: | |
| inputs = req.inputs if req else None | |
| results: list[RunResult] = engine.run(inputs) | |
| return { | |
| "results": [r.model_dump() for r in results], | |
| "matches": sum(1 for r in results if r.matched), | |
| "network": _network_payload(), | |
| } | |
| async def get_stats() -> dict: | |
| return engine.stats.as_dict() | |
| async def get_history() -> dict: | |
| return { | |
| "version": engine.network.version, | |
| "snapshots": [ | |
| { | |
| "version": s.version, | |
| "reason": s.reason, | |
| "timestamp": s.timestamp, | |
| "diagram": to_vis_network(s.nodes, s.edges), | |
| } | |
| for s in engine.network.history | |
| ], | |
| } | |
| async def reset_simulation() -> dict: | |
| engine.reset() | |
| return _network_payload() | |