Skip to main content

Load an existing notebook with local files

A Notebook Kit document on disk often references data files next to it. This recipe reads the document with Python, passes its text to Notebook.from_html, and embeds the referenced CSV so the widget carries its data wherever it renders.

The example writes the document and its data file to a temporary directory first, standing in for a notebook you already have.

from pathlib import Path
import tempfile

import marimo as mo
import observablejs as obs

base = Path(tempfile.mkdtemp(prefix="observable-source-"))
(base / "penguins.csv").write_text(
"species,count\nAdelie,152\nChinstrap,68\nGentoo,124\n",
encoding="utf-8",
)

source = """
<notebook theme="glacier">
<script type="module">
const penguinCounts = FileAttachment("penguins.csv").csv({typed: true});
</script>
<script type="module">
Plot.barY(penguinCounts, {
x: "species",
y: "count",
fill: "species",
tip: {
// This example references a theme variable used by mdx-marimo.
// Replace it with a CSS color or remove `fill` in another host.
fill: "var(--marimo-island-background)"
}
}).plot({
height: 260,
color: {legend: true},
y: {grid: true, label: "Penguins"}
})
</script>
</notebook>
"""
source_path = base / "penguins.html"
source_path.write_text(source, encoding="utf-8")

notebook = obs.Notebook.from_html(
source_path.read_text(encoding="utf-8"),
base_path=source_path.parent,
embed_file_attachments=True,
)
full_view = notebook.view()
mo.ui.anywidget(full_view)

The output renders species counts from the local CSV. The counts come from the Palmer Penguins dataset.

What this shows

  • Path.read_text loads the document text before from_html constructs the source-backed notebook. The glacier theme and both cells come from that string.
  • embed_file_attachments=True discovers the literal FileAttachment("penguins.csv") call, reads the file relative to the explicit base_path, and registers it as a data URL in notebook.attachments.
  • Attachment discovery keeps the input document text unchanged. The attachment registry carries the embedded bytes.

Variations

  • Add rewrite_imports=True when the document imports local JavaScript modules with relative specifiers. They are inlined recursively. See Add files and local modules.
  • Leave embedding disabled when the page already serves the files at the same browser-relative paths.
  • Override notebook values from Python by passing variables= to the constructor, exactly as with authored notebooks.