All docs
Example: your first tool
A complete, runnable package with one load step and one shape step — the smallest tool that shows up on the LSD canvas. Copy, run, and adapt.
The smallest real tool: one node that makes data, one that transforms it. Run the two Python
blocks below in your authoring environment. To put the nodes on the Desktop canvas, use the
Local package workflow: place this tool.py in the scaffold's code module,
link the manifest-backed folder from the source-development CLI, then enable it in
Settings → Project Packages. Restart Desktop after editing a linked Local package.
Opening a .lsd file does not load neighboring Python. For a project-only experiment, save the
code as steps.py beside the project and use the visible Enable project code… control to
review it. Run Once uses an immutable snapshot; Trust Folder & Enable Live Development
permits subsequent saved edits to reload. That choice belongs to the human using Desktop.
The code#
# tool.py
from lsdtools import Tool, Table
tool = Tool("hello", label="Hello")
@tool.load
def numbers(count: int = 5) -> Table:
"""Emit a table of the first `count` integers and their squares."""
xs = list(range(count))
return Table({"n": xs, "square": [x * x for x in xs]})
@tool.shape
def top(t: Table, limit: int = 3) -> Table:
"""Keep the `limit` rows with the largest square."""
return t.sort("square", descending=True).head(limit)
What each line does#
tool = Tool("hello")— oneToolper package, created at module scope. Its name namespaces the nodes (hello.numbers,hello.top).@tool.load— makes a node that produces data.count: int = 5has a default, so it is an optional parameter and renders as a number field.Table({...})— builds aTablefrom a dict of columns.@tool.shape— makes a transform node.t: Tableis an input port (wire it from the load node);limit: intis another parameter.- Every function returns a step, never data at import time — LSD runs it when the node runs.
Run it in Python#
You don't need the desktop to try it — wire the steps and run with an Engine:
from lsdtools import Engine
n = numbers(count=6)
result = Engine().run(top(n, limit=3))
result.output.print()
# → n:[5,4,3] square:[25,16,9]
top(n, ...) wires the shape node's input port to the load node n. Engine().run(...) executes
the chain and caches each step; result.output is the final Table.
Try changing it#
- Add a
@tool.delivernode that callst.write_csv("out.csv"). - Give
numbersaSourceparameter to load a real file instead — see File loader. - Add a second output with
outputs=["evens", "odds"]— see Multi-output.
Related#
Learn — Load steps · Shape steps · Develop a package