diff --git a/nbconvert/preprocessors/execute.py b/nbconvert/preprocessors/execute.py index 205f9efc9..45587d345 100644 --- a/nbconvert/preprocessors/execute.py +++ b/nbconvert/preprocessors/execute.py @@ -480,6 +480,7 @@ def run_cell(self, cell, cell_index=0): continue elif msg_type.startswith('comm'): self.handle_comm_msg(outs, msg, cell_index) + self.widget_state[content['comm_id']] = content['data']['state'] continue display_id = None @@ -556,3 +557,16 @@ def executenb(nb, cwd=None, km=None, **kwargs): resources['metadata'] = {'path': cwd} ep = ExecutePreprocessor(**kwargs) return ep.preprocess(nb, resources, km=km)[0] + + +def _serialize_widget_state(state): + """Serialize a widget state, following format in @jupyter-widgets/schema. + + TODO: Does not currently split binary buffers or remove default values. + """ + return { + 'model_name': state['_model_name'], + 'model_module': state['_model_module'], + 'model_module_version': state.get('_model_module_version'), + 'state': state, + } diff --git a/nbconvert/preprocessors/tests/files/widget-hello-world.ipynb b/nbconvert/preprocessors/tests/files/widget-hello-world.ipynb new file mode 100644 index 000000000..2b56b0ccc --- /dev/null +++ b/nbconvert/preprocessors/tests/files/widget-hello-world.ipynb @@ -0,0 +1,47 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "c3f75dd69f3e4602989aaa3711d2977d", + "version_major": 2, + "version_minor": 0 + }, + "text/html": [ + "
Failed to display Jupyter Widget of type Label
.
\n", + " If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean\n", + " that the widgets JavaScript is still loading. If this message persists, it\n", + " likely means that the widgets JavaScript library is either not installed or\n", + " not enabled. See the Jupyter\n", + " Widgets Documentation for setup instructions.\n", + "
\n", + "\n", + " If you're reading this message in another frontend (for example, a static\n", + " rendering on GitHub or NBViewer),\n", + " it may mean that your frontend doesn't currently support widgets.\n", + "
\n" + ], + "text/plain": [ + "Label(value='Hello World')" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import ipywidgets\n", + "ipywidgets.Label('Hello World')" + ] + } + ], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/nbconvert/preprocessors/tests/test_execute.py b/nbconvert/preprocessors/tests/test_execute.py index fea201eeb..242d54193 100644 --- a/nbconvert/preprocessors/tests/test_execute.py +++ b/nbconvert/preprocessors/tests/test_execute.py @@ -57,6 +57,9 @@ def normalize_output(output): if 'text/plain' in output.get('data', {}): output['data']['text/plain'] = \ re.sub(addr_pat, '