Add files and local modules
files registers named inputs for Observable's FileAttachment builtin.
Local files are read during Notebook construction and sent to the browser
as data URLs, so the widget carries its data wherever it renders.
from pathlib import Path
import tempfile
import marimo as mo
import observablejs as obs
data_dir = Path(tempfile.mkdtemp(prefix="observable-files-"))
(data_dir / "counts.csv").write_text(
"species,count\nAdelie,152\nChinstrap,68\nGentoo,124\n",
encoding="utf-8",
)
notebook = obs.Notebook(
obs.js(
'const speciesCounts = FileAttachment("counts.csv").csv({typed: true});',
key="species_counts",
display=False,
),
obs.js(
"""
Plot.barY(speciesCounts, {
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"}
})
""",
key="chart",
),
files={"counts.csv": "counts.csv"},
base_path=data_dir,
)
full_view = notebook.view()
mo.ui.anywidget(full_view)
The mapping key is the name used by FileAttachment. typed: true asks the
CSV reader to convert values such as numbers and dates. The counts come from
the Palmer Penguins
dataset.
Accepted files values
Each value can be a local path, a URL, or a prepared attachment record.
notebook = obs.Notebook(
obs.ojs('countries = FileAttachment("countries.json").json()'),
files={
"countries.json": {
"url": "https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json",
"mimeType": "application/json",
}
},
)
Relative local paths resolve against base_path, which defaults to the
current working directory. See File
attachments for path resolution, record
shapes, and browser access methods.
Discover files in source HTML
Notebook.from_html can discover local files referenced by literal
FileAttachment("name") calls and embed them as data URLs:
from pathlib import Path
import observablejs as obs
source_path = Path("notebooks/report.html")
notebook = obs.Notebook.from_html(
source_path.read_text(encoding="utf-8"),
base_path=source_path.parent,
embed_file_attachments=True,
)
embed_file_attachments=Truediscovers localFileAttachment("...")references in notebook script cells and embeds each file as a data URL.rewrite_imports=Trueinlines local modules referenced by quoted relative specifiers in static imports,export ... fromdeclarations, and dynamicimport(...)calls, following local imports recursively. Computed specifiers and paths that do not resolve to files stay unchanged.
Both options need a base_path because the source string has no filesystem
location. Choose the directory that should resolve the document's relative
attachment and module paths.
Leave both options false when the page already serves the referenced files at
the same relative paths. When discovery is enabled, an explicit files entry
takes precedence over a discovered file with the same name.
Use URL-backed attachments for large data that the browser should load outside widget state. Local files are embedded as data URLs and increase the synchronized payload.