Skip to content

Commit

Permalink
WIP refactor: fetch the full widget state via a control Comm
Browse files Browse the repository at this point in the history
  • Loading branch information
maartenbreddels authored and martinRenou committed Oct 11, 2021
1 parent fc84ae5 commit b6f6dbc
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 1 deletion.
1 change: 1 addition & 0 deletions ipywidgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def register_comm_target(kernel=None):
if kernel is None:
kernel = get_ipython().kernel
kernel.comm_manager.register_target('jupyter.widget', Widget.handle_comm_opened)
kernel.comm_manager.register_target('jupyter.widget.control', Widget.handle_comm_opened_control)

# deprecated alias
handle_kernel = register_comm_target
Expand Down
10 changes: 9 additions & 1 deletion ipywidgets/widgets/tests/test_send_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from traitlets import Bool, Tuple, List

from .utils import setup, teardown
from .utils import setup, teardown, DummyComm

from ..widget import Widget

Expand All @@ -23,3 +23,11 @@ def test_empty_hold_sync():
with w.hold_sync():
pass
assert w.comm.messages == []


def test_control():
comm = DummyComm()
Widget.close_all()
w = SimpleWidget()
Widget.handle_comm_opened_control(comm, {})
assert comm.messages
20 changes: 20 additions & 0 deletions ipywidgets/widgets/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,26 @@ def _call_widget_constructed(widget):
if Widget._widget_construction_callback is not None and callable(Widget._widget_construction_callback):
Widget._widget_construction_callback(widget)

@classmethod
def handle_comm_opened_control(cls, comm, msg):
cls.get_manager_state()
widgets = Widget.widgets.values()
# build a single dict with the full widget state
full_state = {}
drop_defaults = False
for widget in widgets:
full_state[widget.model_id] = {
'model_name': widget._model_name,
'model_module': widget._model_module,
'model_module_version': widget._model_module_version,
'state': widget.get_state(drop_defaults=drop_defaults),
}
full_state, buffer_paths, buffers = _remove_buffers(full_state)
# the message is also send as buffer, so it does not get handled by jupyter_server
msg = jsondumps([full_state, buffer_paths]).encode('utf8')
buffers.insert(0, msg)
comm.send(buffers=buffers)

@staticmethod
def handle_comm_opened(comm, msg):
"""Static method, called when a widget is constructed."""
Expand Down

0 comments on commit b6f6dbc

Please sign in to comment.