Python API Overview¶
PyNodeWidget's Python API consists of several key modules that work together to create interactive node-based UIs in Jupyter notebooks.
Core Components¶
NodeFlowWidget¶
The main widget for creating and managing node-based workflows. This is your entry point for creating interactive node graphs in Jupyter.
Key Features:
- Register and manage node types
- Access and modify node values
- Import/export workflows as JSON
- Bidirectional synchronization with UI
JsonSchemaNodeWidget¶
Base class for creating custom node types. Implements the NodeFactory protocol and provides a convenient way to define nodes using Pydantic models.
from pynodewidget import JsonSchemaNodeWidget
class MyNode(JsonSchemaNodeWidget):
label = "My Node"
parameters = MyParamsModel
inputs = [{"id": "in", "label": "Input"}]
outputs = [{"id": "out", "label": "Output"}]
Key Features:
- Pydantic-based parameter definition
- Automatic UI generation
- Validation and type safety
- Optional execute() method for processing logic
ObservableDict¶
Auto-syncing dictionary that triggers callbacks on mutations. Used internally for efficient Python-JavaScript synchronization.
from pynodewidget import ObservableDict
data = ObservableDict(callback=lambda: print("changed"))
data["key"] = "value" # Triggers callback
Protocols¶
Protocol definitions for extending PyNodeWidget with custom node factories.
Quick Reference¶
Creating a Widget¶
from pynodewidget import NodeFlowWidget, JsonSchemaNodeWidget
from pydantic import BaseModel, Field
# Define parameters
class ProcessorParams(BaseModel):
threshold: float = Field(default=0.5, ge=0, le=1)
# Define node class
class ProcessorNode(JsonSchemaNodeWidget):
label = "Processor"
parameters = ProcessorParams
icon = "⚙️"
inputs = [{"id": "in", "label": "Input"}]
outputs = [{"id": "out", "label": "Output"}]
# Create widget
flow = NodeFlowWidget(nodes=[ProcessorNode])
flow
Accessing Node Values¶
# Get all values for a node
values = flow.get_node_values("node-1")
# Update a single value
flow.update_node_value("node-1", "threshold", 0.8)
# Get a specific value
threshold = flow.get_node_value("node-1", "threshold", default=0.5)
# Set multiple values
flow.set_node_values("node-1", {"threshold": 0.8, "enabled": True})
Registering Node Types¶
# Register during initialization
flow = NodeFlowWidget(nodes=[Node1, Node2, Node3])
# Register after initialization
flow.register_node_type(Node4)
flow.register_node_type(Node5, type_name="custom_name")
Import/Export¶
# Export workflow to file
flow.export_json("my_workflow.json")
# Load workflow from file
flow.load_json("my_workflow.json")
# Export as dict
workflow_data = flow.get_flow_data()
# Access nodes and edges
nodes = flow.nodes
edges = flow.edges
Type System¶
PyNodeWidget uses Pydantic for type-safe parameter definitions:
from pydantic import BaseModel, Field
from typing import Literal
class NodeParams(BaseModel):
# String with validation
name: str = Field(min_length=1, max_length=50)
# Number with range
threshold: float = Field(ge=0, le=1)
# Integer
count: int = Field(default=10, ge=1)
# Boolean
enabled: bool = True
# Enum (becomes dropdown)
mode: Literal["auto", "manual", "advanced"] = "auto"
# Optional field
description: str | None = None
These automatically generate appropriate UI inputs:
str→ Text inputint,float→ Number inputbool→ CheckboxLiteral/ Enum → Dropdown- Optional → Nullable field
Advanced Features¶
Conditional Fields¶
Show/hide fields based on other field values:
fieldConfigs = {
"threshold": {
"showWhen": {
"field": "mode",
"operator": "equals",
"value": "advanced"
}
}
}
node = JsonSchemaNodeWidget.from_pydantic(
MyParams,
label="Advanced",
fieldConfigs=fieldConfigs
)
Custom Styling¶
config = {
"header": {
"show": True,
"icon": "✨",
"className": "bg-gradient-to-r from-blue-500 to-purple-500 text-white"
},
"style": {
"minWidth": "300px",
"shadow": "lg",
"borderRadius": "12px"
}
}
node = JsonSchemaNodeWidget.from_pydantic(MyParams, **config)
Node Execution¶
Implement custom processing logic:
class ProcessorNode(JsonSchemaNodeWidget):
label = "Processor"
parameters = ProcessorParams
def execute(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
"""Execute node logic."""
# Get configuration
config = self.get_values()
threshold = config["threshold"]
# Get input data
data = inputs.get("data_in")
# Process
filtered = [x for x in data if x >= threshold]
# Return outputs
return {"data_out": filtered}
Next Steps¶
- NodeFlowWidget Reference: Complete widget API
- JsonSchemaNodeWidget Reference: Node creation API
- User Guides: Practical tutorials