from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException from app.db import Database from app.node_manager import NodeManager from app.schemas import InvokePayload, NodeCreate from wov_sdk.models import InvokeRequest router = APIRouter(prefix="/api/admin/nodes", tags=["nodes"]) def _get_db() -> Database: from app.main import app return app.state.db def _get_manager() -> NodeManager: from app.main import app return app.state.node_manager @router.post("") def register_node(payload: NodeCreate, db: Database = Depends(_get_db)) -> dict: manifest = payload.to_manifest() try: manifest.validate() except ValueError as exc: raise HTTPException(status_code=422, detail=str(exc)) from exc db.upsert_node(manifest) return manifest.to_dict() @router.get("") def list_nodes(db: Database = Depends(_get_db)) -> list[dict]: return [manifest.to_dict() for manifest in db.list_nodes()] @router.get("/{node_id}") def get_node(node_id: str, db: Database = Depends(_get_db)) -> dict: manifest = db.get_node(node_id) if manifest is None: raise HTTPException(status_code=404, detail="node not found") return manifest.to_dict() @router.delete("/{node_id}") def delete_node( node_id: str, db: Database = Depends(_get_db), manager: NodeManager = Depends(_get_manager), ) -> dict: if db.get_node(node_id) is None: raise HTTPException(status_code=404, detail="node not found") manager.stop_all_for_node(node_id) db.delete_node(node_id) return {"deleted": node_id} @router.post("/{node_id}/invoke") def invoke_node( node_id: str, payload: InvokePayload, manager: NodeManager = Depends(_get_manager), ) -> dict: from app.config import STORAGE_DIR output_dir = ( STORAGE_DIR / "runs" / payload.run_id / "steps" / node_id ) request = InvokeRequest( run_id=payload.run_id, node_instance_id="", inputs=payload.inputs, params=payload.params, output_dir=str(output_dir), ) response = manager.invoke(node_id, request) return response.to_dict() @router.get("/{node_id}/instances") def list_node_instances( node_id: str, db: Database = Depends(_get_db), ) -> list[dict]: if db.get_node(node_id) is None: raise HTTPException(status_code=404, detail="node not found") return [ instance for instance in db.list_instances() if instance["node_id"] == node_id ]