Skip to main content

Notebooking

Notebooks are OSO's unit of analysis: a marimo notebook that queries the warehouse and renders charts, tables, and text. You can build one in the OSO app or author it locally and run it on OSO's hosted marimo. Notebooks usually query the marts you've explored and the models you've built.

Build in the app

Open your workspace, create a new notebook, and write cells that query OSO with SQL and render the results. The notebook runs live against your data.

Author locally

note

Building in the app? You can skip this section — these rules only apply when you author a notebook locally and run it on OSO's hosted marimo.

For a locally authored notebook to run on OSO's hosted marimo (marimo.oso.xyz), it must follow a few rules that keep it interoperable with the platform.

  • Don't pin a marimo version. The file header must be __generated_with = "unknown".

  • Keep the setup_pyoso cell verbatim. It provides mo and a pyoso_db_conn every other cell uses. Never modify its body (you may add hide_code=True):

    @app.cell(hide_code=True)
    def setup_pyoso():
    import pyoso
    import marimo as mo

    pyoso_db_conn = pyoso.Client().dbapi_connection()
    return mo, pyoso_db_conn
  • Query with mo.sql, not a raw client. Run SQL through the shared connection, never by constructing pyoso.Client() inside a cell:

    @app.cell(hide_code=True)
    def _(mo, pyoso_db_conn):
    df_projects = mo.sql("SELECT * FROM oso.projects_v1 LIMIT 5", engine=pyoso_db_conn)
    return (df_projects,)
  • Set hide_code=True on every cell.

  • Give each cell's outputs unique names (df_projects, not df). Marimo enforces a single-definition rule across the notebook.

  • No local file access. Pull all data through mo.sql, so the notebook runs the same locally and on the platform.

Validate a local notebook before publishing:

uv run marimo check your_notebook.py

Publish

Publishing renders your notebook to a static HTML snapshot others can open without re-running it. Publishing and sharing are separate steps: publishing creates the snapshot; making it visible to others is a permission grant covered in Publishing & sharing.

In the app

Open the notebook and choose Publish. OSO renders the current state to a snapshot. If you have admin access, saving a content change re-publishes automatically, so the snapshot stays current with your edits.

From your agent

Over MCP, the publish loop is:

  1. createNotebookUploadUrl for a presigned URL, then upload the notebook body. This is the path for larger notebooks; smaller ones can be sent inline via createNotebook / updateNotebook.
  2. publishNotebook to render and store the snapshot.
  3. updateNotebook for content changes, which re-publishes automatically when the caller has admin.

The snapshot is rendered once, at publish time, under the publisher's identity, so a reader sees the data exactly as the publisher could query it then.

Next