Variables and serialization
variables sends named Python values to the Observable notebook.
import observablejs as obs
notebook = obs.Notebook(
obs.ojs("md`threshold is ${threshold}`", key="readout"),
variables={"threshold": 0.75},
)
Variable names
Names must match ^[A-Za-z_$][0-9A-Za-z_$]*$. Observable runtime builtins such
as Inputs, Plot, FileAttachment, width, and invalidation are reserved.
ObservableHQ sources also reserve classic runtime names such as require.
Invalid or reserved names raise ValueError.
Write variables
notebook.update_variables({"threshold": 0.8})
notebook.replace_variables({"rows": rows})
notebook.reset_variables("threshold")
update_variables(values, /) merges exactly one mapping.
replace_variables(values, /) replaces the complete mapping sent from Python.
reset_variables(*names) removes selected Python values so the notebook can
define them again. Keyword updates, pair iterables, and None are invalid for
update and replacement.
Sending the same serialized value does not emit a controller state event. It
is also a browser no-op unless the browser has changed a shared input with that
name. In that case, the update clears the browser-owned value and reapplies the
Python value. A real change reaches every active view.
Read controller variables
Notebook.variables is the variable mapping from the latest
NotebookState. It is detached from construction inputs and recursively
read-only. After serialization, sequences are tuples, nested mappings are
read-only, byte-like values are bytes, and DataFrame-like inputs are row records.
def on_state(change):
print(change["new"].variables)
notebook.observe(on_state, names="state")
Mutating the snapshot cannot update the notebook. Use the mutation methods for writes.
Python to browser conversion
| Python input | Browser value |
|---|---|
None, bool, str | null, boolean, string |
Safe int, finite float | number |
Large int | BigInt |
NaN and infinities | matching JavaScript number |
date, datetime | Date |
bytes, bytearray, memoryview | Uint8Array |
| Mapping | plain object |
| Range, sequence, iterable | array |
| pandas or Polars DataFrame | array of row objects |
| pandas or Polars Series, NumPy array | array |
One-shot iterators materialize once. Unsupported values raise TypeError
before state changes. Use file attachments for data
that should load through FileAttachment.
Shared viewof inputs
When a Python variable and named viewof input use the same name, the initial
Python value sets the control. Browser changes then update sibling views. A
later Python update sets the value again in every view. Use the same input shape
for a shared name across views.
Browser result conversion
Cell values in NotebookView.state decode into detached read-only mappings.
| Browser value | Python result value |
|---|---|
undefined, null | None |
| Number, boolean, string | JSON-compatible scalar |
BigInt | int |
Valid Date | datetime.datetime |
| Array, plain object | tuple or read-only mapping |
Map, Set | tuple-based records |
| Array buffer or typed array | bytes |
Error returned as data | BrowserErrorValue |
| DOM element, function, regular expression | stable summary string |
File, Blob | read-only metadata mapping |
Evaluation, rendering, and serialization failures appear in structured
CellError records. See View state and graph.