Bidirectional inputs
One named input can receive updates from Python and the browser. The Python
slider writes through update_variables. The Observable slider changes the
browser value, and a Python readout follows the finished result.
Create and display the Python control in its own marimo cell.
import marimo as mo
import observablejs as obs
python_gain = mo.ui.slider(
start=0,
stop=12,
value=5,
label="Set gain from Python",
)
python_gain
Create and display the browser view in another cell.
notebook = obs.Notebook(
obs.ojs(
'viewof gain = Inputs.range([0, 12], {value: 5, step: 1, label: "Gain in the browser"})',
key="gain_control",
),
obs.js(
"""
Plot.barY(
Array.from({length: 8}, (_, index) => (index + 1) * gain),
{
x: (_, index) => index + 1,
y: (value) => value,
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: 220, x: {label: "Step"}, y: {grid: true}})
""",
key="chart",
),
variables={"gain": 5},
)
view = notebook.view()
widget = mo.ui.anywidget(view)
widget
Send Python slider changes from a cell that references python_gain and
notebook.
notebook.update_variables({"gain": python_gain.value})
Read the current browser value after the latest input revision settles.
widget.value # subscribe this cell to view synchronization
state = view.state
if (
not state.pending
and state.input_revision is not None
and state.settled_revision == state.input_revision
):
gain = state.result("gain_control")
gain_report = (
f"Python reads `gain = {gain.values['gain']}`."
if gain.status == "success"
else f"Browser error: {gain.errors}"
)
else:
gain_report = "Waiting for the Observable view to render."
mo.md(gain_report)
Each direction has one path:
- The Python slider calls
update_variables. - The Observable slider updates the named
viewof gaininput. - The synchronized anywidget state updates
view.state. - The readout displays the finished
gain_controlresult.
The Python slider shows the last value Python sent. The Observable slider and readout show the current browser value.
Shared input state supports JSON-like values, BigInt, dates, maps, and sets.
Functions, DOM elements, files, and binary buffers stay in the view where they
were created. Use the same input shape for a shared name across views.
See Widget composition for separate views and Variables and serialization for the value boundary.