Skip to content

peter-gy/pymalloy

unversioned · fc5a65722040

Author, inspect, and verify Malloy semantic models from Python.

PyMalloy

Author, check, run, and share Malloy models from Python. Compose models with Python expressions or edit existing Malloy source. Malloy compiles the queries, and DuckDB executes them.

Author and run a model

pip install 'pymalloy[headless]'
import pymalloy as pm

orders = pm.sql("SELECT * FROM (VALUES ('North', 20), ('North', 22)) t(region, amount)")
candidate = (
    pm.draft()
    .define(orders=orders.extend(
        pm.measure(revenue=pm.col("amount").sum().doc("Booked amount in USD.")),
    ).doc("One row per order."))
    .queries(by_region=pm.ref("orders").pipe(pm.query(
        pm.group_by(pm.col("region")),
        pm.aggregate(pm.col("revenue")),
    )))
)

print(candidate.text)                 # Ordinary Malloy source
print(pm.run(candidate).rows())       # [{'region': 'North', 'revenue': Decimal('42')}]

Drafts are immutable. Check them with Malloy, validate assumptions with named counterexample queries, and package accepted models with their captured inputs. Use pm.data(frame) to bring prepared Python data into the model as portable Parquet. Retain the producing notebook or script for preparation logic.

Explore in a browser widget

pip install 'pymalloy'
from pymalloy import MalloyWidget

widget = MalloyWidget("run: duckdb.sql('SELECT 42 AS answer') -> { select: answer }")
widget

Display the widget in Jupyter or marimo. Malloy and DuckDB WebAssembly run in the browser. The base install includes widgets and agent guidance, without Deno. First use downloads DuckDB WebAssembly and needs browser worker support.

Learn more

For the included versioned agent instructions, import pymalloy.agent and start with help(pymalloy.agent).

Examples · Contributing