Interface — Defining Node Specs and UI
Node Specs: Inputs and Outputs
Every node has a prototype that declares its interface:
from flet_nodes import InputSpec, OutputSpec
inputs = [
InputSpec(id='a', displayName='Number A', type='double', default=0.0),
InputSpec(id='b', displayName='Number B', type='double', default=0.0)
]
outputs = [
OutputSpec(id='result', displayName='Sum', type='double')
]
InputSpec
id: Internal identifier (used by logic code)displayName: Human-readable label in UItype: Optional hint—'double','string','boolean','any'default: Fallback value if port is not connected
OutputSpec
id: Internal identifier (must match keys returned by logic)displayName: User-facing labeltype: Output type hint
Creating Nodes Programmatically
Use NodesField to add nodes to the editor from Python:
from flet_nodes import NodesField, InputSpec, OutputSpec
nf = NodesField(expand=True) # embedded in a Flet control
await nf.add_node(
prototype='math.add', # must be registered
x=100, y=100, # canvas position
name='Add Numbers', # display name in UI
inputs=inputs,
outputs=outputs
)
UI Content as Fallback Input
Nodes can have optional UI controls that provide values when a port is not connected:
from flet import TextField
ui_content = TextField(label='Value', value='42')
await nf.add_node(
prototype='my.input',
ui_content=ui_content,
...
)
When the node executes, logic code can read from this control if no connected input exists.
Best Practices
- Keep UI concerns in Flet: Rendering, user events, button clicks
- Put logic in Python classes: All computation goes in
BaseNodeLogic.execute() - Use clear IDs:
'math.add','string.concat'—make it obvious what the node does - Document types: Help users understand what data flows through each port
- Provide sensible defaults: So nodes work even if not fully connected