Skip to content

Commit 110f866

Browse files
committed
Be more lazy about initializing widget state on the front-end
1 parent 57e6371 commit 110f866

File tree

1 file changed

+28
-15
lines changed

1 file changed

+28
-15
lines changed

shinywidgets/_shinywidgets.py

+28-15
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,6 @@ def _cleanup_session_state():
9696

9797
session.on_ended(_cleanup_session_state)
9898

99-
# Get the initial state of the widget
100-
state, buffer_paths, buffers = _remove_buffers(w.get_state())
101-
10299
# Make sure window.require() calls made by 3rd party widgets
103100
# (via handle_comm_open() -> new_model() -> loadClass() -> requireLoader())
104101
# actually point to directories served locally by shiny
@@ -114,18 +111,34 @@ def _cleanup_session_state():
114111

115112
id = cast(str, w._model_id)
116113

117-
# Initialize the comm...this will also send the initial state of the widget
118-
with widget_comm_patch():
119-
w.comm = ShinyComm(
120-
comm_id=id,
121-
comm_manager=COMM_MANAGER,
122-
target_name="jupyter.widgets",
123-
data={"state": state, "buffer_paths": buffer_paths},
124-
buffers=cast(BufferType, buffers),
125-
# TODO: should this be hard-coded?
126-
metadata={"version": __protocol_version__},
127-
html_deps=session._process_ui(TagList(widget_dep))["deps"],
128-
)
114+
# Schedule the opening of the comm to happen sometime after this init function.
115+
# This is important for widgets like plotly that do additional initialization that
116+
# is required to get a valid widget state.
117+
@reactive.effect(priority=99999)
118+
def _open_comm():
119+
120+
# Call _repr_mimebundle_() before getting the state since it may modify the widget
121+
# in an important way (unfortunately, plotly does this)
122+
# # https://github.com/plotly/plotly.py/blob/0089f32/packages/python/plotly/plotly/basewidget.py#L734-L738
123+
w._repr_mimebundle_()
124+
125+
# Now, get the state
126+
state, buffer_paths, buffers = _remove_buffers(w.get_state())
127+
128+
# Initialize the comm -- this sends widget state to the frontend
129+
with widget_comm_patch():
130+
w.comm = ShinyComm(
131+
comm_id=id,
132+
comm_manager=COMM_MANAGER,
133+
target_name="jupyter.widgets",
134+
data={"state": state, "buffer_paths": buffer_paths},
135+
buffers=cast(BufferType, buffers),
136+
# TODO: should this be hard-coded?
137+
metadata={"version": __protocol_version__},
138+
html_deps=session._process_ui(TagList(widget_dep))["deps"],
139+
)
140+
141+
_open_comm.destroy()
129142

130143
# If we're in a reactive context, close this widget when the context is invalidated
131144
# TODO: this should probably only be done in an output context, but I'm pretty sure

0 commit comments

Comments
 (0)