Skip to main content

Data namespaces

cells, files, data, and graph group the notebook's inspection and data operations. Conversions return Python objects directly.

notebook.cells["result"].source
notebook.files["sales.csv"].url
notebook.data["sales"].to_polars()
notebook.graph.upstream("result")

notebook.data and notebook.graph use the optional headless runtime. Files and cell handles work with the base installation. Live widget reads use the specific view's browser and require no Deno:

frame = await view.data["sales"].to_polars()
raw = await view.files["sales.csv"].read_bytes()
graph = await view.graph.snapshot()

Cells and variables

notebook.cells[key] selects a canonical cell by public key. Integer indexing and iteration follow notebook order. cells.keys() lists authored keys. cell.source, mode, id, index, hidden, and pinned describe its definition.

Data names identify JavaScript variables, independently of cell keys:

cell = notebook.cells["calculation"]
total = notebook.data["total"].to_python()
local_total = cell.data["total"].to_python()

notebook.data.names() analyzes declarations without evaluating cells or fetching imports. await view.data.names() obtains the displayed view's static analysis. Looking up a notebook data reference validates its name through static analysis. Printing references does not evaluate values or download files.

Data references

OperationResult
reference.to_python()Detached Python scalar, list, dictionary, bytes, or other supported value
reference.to_polars()polars.DataFrame
reference.to_pandas()pandas.DataFrame
reference.to_arrow()pyarrow.Table
reference.describe()DataDescription with kind, schema, row count, and inference metadata

Headless methods are synchronous. The same methods on view.data[name] are awaitable. Each conversion waits for its requested value. It does not require a separate readiness call.

Install the target library to use its converter. Polars reads Arrow IPC directly and does not require pandas or PyArrow. Pandas conversion uses PyArrow-backed nullable columns, preserving missing values and large integers. Install both pandas and PyArrow for to_pandas().

frame = notebook.data["sales"].to_polars(
columns=["year", "amount"], offset=0, limit=1000
)

Converters accept columns, offset, limit, path, and timeout=30. Projection and row ranges apply before transfer. path selects stored nested properties before conversion. Methods fail when the requested representation cannot preserve the value. JavaScript functions and DOM objects require an appropriate computed value or a rendered artifact.

to_python() keeps primitive arrays as lists and table values as records. Python results are detached from the runtime and can be mutated locally. Dates, large integers, and non-finite numbers follow the value conversion contract.

Descriptions and sources

reference = notebook.data["sales"]
print(reference.cell)
print(reference.sources)
description = reference.describe()
print(description.schema, description.row_count)

DataDescription includes kind, schema, row_count, schema_source, and sampled_rows. Schemas map column names to native or inferred type descriptions. schema_source="native" identifies declared schema metadata. "sampled" identifies inference from a bounded sample. Scalar values have no table schema or row count.

sources reports known attachment references and literal fetch() or D3 loader URLs from the producing cell and its dependencies. Each source records kind, name, url, and provenance="static". These are source references, not proof of observed network traffic. Dynamic URLs and imported notebooks can have additional sources. Async references have cell=None and sources=None until analysis is available.

A derived dataset can combine several sources. Its data reference has no singular URL. A file reference's url describes the original attachment.

Discovery

catalog = notebook.data.discover()
for dataset in catalog.datasets:
print(dataset.name, dataset.describe())
frame = catalog.datasets["sales"].to_polars()

Discovery evaluates the requested cells and dependencies, or the full notebook when no selectors are supplied. It returns recognized datasets and diagnostics. An unrelated cell failure does not discard available datasets. catalog.pending marks incomplete evaluation. A synchronous infinite loop still raises a timeout and closes its execution.

catalog.datasets supports names, integer positions, and iteration. Duplicate names require positional selection. References pin the discovered runtime and value revision. A changed value or replaced runtime raises a stale-read error. Look up a new reference when the latest value is intended.

For a widget, discovery uses the view's evaluated selection:

catalog = await view.data.discover()
frame = await catalog.datasets["sales"].to_polars()

Discovery and full reads work with capture_state=False.

Files

file = notebook.files["sales.csv"]
print(file.url, file.mime_type, file.size)
raw = file.read_bytes()
frame = file.to_polars()
config = notebook.files["config.json"].to_python()

Files expose read_bytes(), to_python(), to_polars(), to_pandas(), and to_arrow(). Format inference uses filename, declared content type, and content signatures. For an ambiguous file, pass format="csv", "tsv", "json", "ndjson", "arrow", "parquet", or "text". Text is not tabular.

JSON objects become one dataframe row with nested fields preserved. Arrays of objects become rows, and scalar arrays become a value column. to_python() retains the original JSON structure. CSV dataframe readers inspect all rows for type inference. Text such as NA remains text rather than becoming a missing value. to_python() preserves CSV fields as strings.

Computed fields added to query rows remain accessible even if the notebook retains older schema metadata. Table columns are enumerable string properties. Symbol properties used by visualization libraries for bookkeeping are not columns. Callables and incompatible mixed column types still require an explicit projection or access as a Python structure when representable. Duplicate CSV headers are rejected before a column can be lost. Mixed JSON column types fail explicitly rather than coercing numbers to strings. The original structure remains available through to_python() for JSON, and read_bytes() always provides the file contents.

Advanced parser options belong to the target library:

from io import BytesIO
import polars as pl

frame = pl.read_csv(BytesIO(file.read_bytes()), schema_overrides={"id": pl.String})

Notebook file reads use Python I/O. await view.files[name].read_bytes() uses the originating browser, including its URL resolution and credentials. A statically referenced file with an unresolved URL must be read through that view.

Async access and live snapshots

Headless and Python file reads have explicit async accessors:

frame = await notebook.data.aio["sales"].to_polars()
raw = await notebook.files.aio["sales.csv"].read_bytes()

Headless requests support cancellation. File I/O runs on a worker thread, bounded by its socket timeout. The synchronous methods remain the default.

For reactive applications, the readonly view.inspection, view.datasets, and view.diagnostics traits publish browser metadata independently of preview capture. Observe them with traitlets. Use the namespaces for materialization.

Jupyter supports awaited view reads in a cell after display. In marimo, schedule the read in a background task so the executing cell can finish and process the browser response. See the inspection guide.