@@ -96,9 +96,6 @@ def _cleanup_session_state():
96
96
97
97
session .on_ended (_cleanup_session_state )
98
98
99
- # Get the initial state of the widget
100
- state , buffer_paths , buffers = _remove_buffers (w .get_state ())
101
-
102
99
# Make sure window.require() calls made by 3rd party widgets
103
100
# (via handle_comm_open() -> new_model() -> loadClass() -> requireLoader())
104
101
# actually point to directories served locally by shiny
@@ -114,18 +111,34 @@ def _cleanup_session_state():
114
111
115
112
id = cast (str , w ._model_id )
116
113
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 ()
129
142
130
143
# If we're in a reactive context, close this widget when the context is invalidated
131
144
# TODO: this should probably only be done in an output context, but I'm pretty sure
0 commit comments