pytrace/server/app/api/endpoints_graph.py
2026-01-19 00:49:55 +08:00

80 lines
2.5 KiB
Python

from fastapi import APIRouter, HTTPException
from pytrace.core.registry import NodeRegistry
from pytrace.core.executor import WorkflowExecutor
from pytrace.model.graph import WorkflowGraph, Node, Edge
from ..models.graph import GraphExecuteRequest
router = APIRouter()
@router.get("/plugins")
async def get_plugins():
"""
Gets the list of all available (registered) nodes and their specifications.
This is used by the frontend to populate the node palette.
"""
specs = NodeRegistry.get_all_specs()
# The old protocol expects a dictionary keyed by node type string.
plugins = {
spec.type: {
"display_name": spec.name,
"category": spec.category,
"description": spec.description,
"node_type": spec.node_type.value,
"class_name": spec.type, # Using the unique type string as class_name
"inputs": [p.dict() for p in spec.inputs],
"outputs": [p.dict() for p in spec.outputs],
"param_schema": [p.dict() for p in spec.params],
}
for spec in specs
}
return {
"plugins": plugins,
"total": len(plugins),
"categories": NodeRegistry.get_categories()
}
@router.post("/execute")
async def execute_graph(request: GraphExecuteRequest):
"""
Executes a workflow graph.
"""
try:
# 1. Build the WorkflowGraph from the request
graph = WorkflowGraph(name="Execution Graph")
for node_data in request.nodes:
graph.add_node(Node(
id=node_data.id,
type=node_data.type,
name=node_data.name,
params=node_data.params
))
for edge_data in request.edges:
graph.add_edge(Edge(
source_id=edge_data.source_node,
source_port=edge_data.source_port,
target_id=edge_data.target_node,
target_port=edge_data.target_port
))
# 2. Instantiate the executor and run the graph
executor = WorkflowExecutor()
results = executor.execute(graph, initial_inputs=request.initial_inputs)
# 3. Return the results
return {
"success": True,
"results": results
}
except Exception as e:
import traceback
raise HTTPException(
status_code=500,
detail={
"error": str(e),
"type": type(e).__name__,
"traceback": traceback.format_exc()
}
)