Tutorial: write your own node with @node
Any Python function can become a node. You describe its ports and fields with
the @node decorator, save the file, and the node appears in the Library
straight away. You don't need to restart.
1. Where node files go
Put Python files in your project's modules/user_blocks/ folder. Open it
from the Files tab or the Code Editor. EdgeWeave watches the folder and
reloads a file whenever you save it.
modules/user_blocks/example.py in the demo project is a commented
reference. Copying it is a good way to start.
2. A first node
Create modules/user_blocks/clamp.py:
from sdk.node import node
@node(
name="clamp", # registry key: saved in .weave files, so don't rename it later
label="Clamp", # what the Library and the node title show
category="Math", # Library group (new names create new groups)
icon="📌",
inputs=[
{"name": "value", "type": "float", "description": "Number to limit."},
{"name": "lo", "overrides": "lo", "type": "float",
"description": "Lower bound (overrides the field when wired)."},
{"name": "hi", "overrides": "hi", "type": "float",
"description": "Upper bound (overrides the field when wired)."},
],
params={"lo": 0.0, "hi": 1.0}, # fields on the node, with defaults
output_types=[{"name": "clamped", "type": "float",
"description": "value limited to [lo, hi]."}],
codegen="max({lo}, min({hi}, {value}))", # how it appears in Export to Python
)
def clamp(value, lo, hi):
"""Limit a number to a range."""
return float(max(lo, min(hi, value)))
Save it. Clamp appears under Math in the Library and in the Ctrl+K palette. Wire a number into it and click Run.
3. How the pieces fit
-
Ports are passed positionally, in port order; fields are passed as keyword arguments.
-
paramsbecome fields on the node. A bare default sets the control type (0.0gives a number,Falsea checkbox,"text"a text box). For a drop-down, give the full form:params={"mode": {"default": "fast", "label": "Speed","type": "select", "options": ["fast", "slow"]}} -
overrideslinks a port to the field of the same name. When the port is connected, the wired value wins and the field greys out. -
typeanddescriptionon every port and output appear when users hover a port and in the right-click docs panel. Fill them in. -
The docstring is the node's help text (or pass
doc="..."). -
Errors don't crash the run. An exception becomes a red error preview on the node.
-
A DataFrame result gets a table preview automatically.
4. Make it exportable
codegen decides what Export to Python writes for your node:
- a string such as
"max({lo}, min({hi}, {value}))": an expression where{port}and{field}tokens are filled in. Don't put quotes around tokens; values are inserted as Python literals. - a dict with
imports,expr, or atemplatefunction for anything longer. codegen_unavailable="why"if the node genuinely can't be exported. The export then says so instead of producing a broken script.
If you leave codegen out, the node exports as a passthrough with a warning.
5. Next steps
- Bigger nodes: put the real work in a plain function and call it from both the node and its codegen, so the export runs the same code as the app.
- A node with the same
nameas a built-in node replaces it. That's handy for experiments, but pick distinct names for real nodes. - Share your nodes by packaging the folder as a Marketplace module.