LSD Docs

Turn a Python function into a cached, inspectable pipeline node — then build packages and ship them to the Tool Store. Everything runs on lsdtools.

tool.py
from lsdtools import Tool, table, Table

tool = Tool("hello")

@tool.load                          # ← a node in the palette
def cities(count: int = 3) -> Table:    # count → a form field
    return table({
        "city": ["Tokyo", "Delhi", "Lima", "Oslo"][:count],
        "pop":  [37_400_068, 31_181_376, 11_204_000, 717_710][:count],
    })
@tool.shape                     # Table in → Table out
def top_cities(t: Table, limit: int = 10) -> Table:
    """t → an input port; limit → a form field."""
    return (
        t.filter(t["pop"] > 1_000_000)
         .sort("pop", descending=True)
         .head(limit)
    )
from lsdtools import Engine

@tool.deliver                   # Table in → the outside world
def export(t: Table, name: str = "report"):
    t.write_parquet(f"{name}.parquet")

if __name__ == "__main__":
    Engine().run(export(top_cities(cities(count=4))))
    # → report.parquet — every step cached, only changes re-run
from lsdtools import ui

dialog = ui.form(
    ui.number("cutoff", label="Keep above"),
    ui.select("mode", options=["fast", "exact"]),
    rules={"cutoff": [ui.range(0, 100)]},
)
ui.validate(dialog, {"cutoff": 150})  # → {"cutoff": "must be ≤ 100"}

@tool.shape(dialog=dialog)  # field names bind to params — checked at import
def keep(t: Table, cutoff: float = 50, mode: str = "fast") -> Table: ...
from lsdtools import Context

@tool.command("stats", help="Rows, columns, nulls — any CSV")
def stats(ctx: Context, src: str) -> int:
    t = table.read_csv(src)
    print(f"{len(t)} rows × {len(t.columns)} columns")
    t.null_report().print()
    return 0

# $ lsd hello stats people.csv → 3 rows × 2 columns
Type to search every doc, guide, and tutorial.
↑↓ navigate openesc close