diff --git a/nbconvert/exporters/exporter.py b/nbconvert/exporters/exporter.py index 1df594043..1c487ab56 100644 --- a/nbconvert/exporters/exporter.py +++ b/nbconvert/exporters/exporter.py @@ -112,7 +112,7 @@ def __init__(self, config=None, **kw): super().__init__(config=with_default_config, **kw) self._init_preprocessors() - + self._nb_metadata = {} @property def default_config(self): @@ -141,7 +141,12 @@ def from_notebook_node(self, nb, resources=None, **kw): # Preprocess nb_copy, resources = self._preprocess(nb_copy, resources) - + notebook_name = '' + if resources is not None: + name = resources.get('metadata', {}).get('name', '') + path = resources.get('metadata', {}).get('path', '') + notebook_name = os.path.join(path, name) + self._nb_metadata[notebook_name] = nb_copy.metadata return nb_copy, resources def from_filename(self, filename: str, resources: Optional[dict] = None, **kw): diff --git a/nbconvert/exporters/html.py b/nbconvert/exporters/html.py index 9f02b774c..0154defc3 100644 --- a/nbconvert/exporters/html.py +++ b/nbconvert/exporters/html.py @@ -137,7 +137,8 @@ def from_notebook_node(self, nb, resources=None, **kw): langinfo = nb.metadata.get('language_info', {}) lexer = langinfo.get('pygments_lexer', langinfo.get('name', None)) highlight_code = self.filters.get('highlight_code', Highlight2HTML(pygments_lexer=lexer, parent=self)) - filter_data_type = WidgetsDataTypeFilter(notebook_metadata=nb.metadata, parent=self) + + filter_data_type = WidgetsDataTypeFilter(notebook_metadata=self._nb_metadata, parent=self, resources=resources) self.register_filter('highlight_code', highlight_code) self.register_filter('filter_data_type', filter_data_type) @@ -167,7 +168,6 @@ def resources_include_url(name): pieces = split_template_path(name) for searchpath in self.template_paths: filename = os.path.join(searchpath, *pieces) - print(filename, os.path.exists(filename)) if os.path.exists(filename): with open(filename, "rb") as f: data = f.read() diff --git a/nbconvert/exporters/tests/test_templateexporter.py b/nbconvert/exporters/tests/test_templateexporter.py index f08441fef..aee6a60dd 100644 --- a/nbconvert/exporters/tests/test_templateexporter.py +++ b/nbconvert/exporters/tests/test_templateexporter.py @@ -326,6 +326,7 @@ def test_raw_template_init(self): class AttrExporter(RSTExporter): def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) self.raw_template = raw_template exporter_init = AttrExporter() diff --git a/nbconvert/filters/widgetsdatatypefilter.py b/nbconvert/filters/widgetsdatatypefilter.py index 6d390b44e..42833ec70 100644 --- a/nbconvert/filters/widgetsdatatypefilter.py +++ b/nbconvert/filters/widgetsdatatypefilter.py @@ -19,7 +19,7 @@ #----------------------------------------------------------------------------- from warnings import warn - +import os from ..utils.base import NbConvertBase __all__ = ['WidgetsDataTypeFilter'] @@ -33,13 +33,13 @@ class WidgetsDataTypeFilter(NbConvertBase): """ Returns the preferred display format, excluding the widget output if there is no widget state available """ - def __init__(self, notebook_metadata=None, **kwargs): - metadata = notebook_metadata or {} - - self.widgets_state = ( - metadata['widgets'][WIDGET_STATE_MIMETYPE]['state'] if - metadata.get('widgets') is not None else {} - ) + def __init__(self, notebook_metadata=None, resources=None, **kwargs): + self.metadata = notebook_metadata + self.notebook_path = '' + if resources is not None: + name = resources.get('metadata', {}).get('name', '') + path = resources.get('metadata', {}).get('path', '') + self.notebook_path = os.path.join(path, name) super().__init__(**kwargs) @@ -51,12 +51,17 @@ def __call__(self, output): `output` is dict with structure {mimetype-of-element: value-of-element} """ + metadata = self.metadata.get(self.notebook_path, {}) + widgets_state = ( + metadata['widgets'][WIDGET_STATE_MIMETYPE]['state'] if + metadata.get('widgets') is not None else {} + ) for fmt in self.display_data_priority: if fmt in output: # If there is no widget state available, we skip this mimetype if ( fmt == WIDGET_VIEW_MIMETYPE and - output[WIDGET_VIEW_MIMETYPE]['model_id'] not in self.widgets_state + output[WIDGET_VIEW_MIMETYPE]['model_id'] not in widgets_state ): continue diff --git a/nbconvert/tests/files/Unexecuted_widget.ipynb b/nbconvert/tests/files/Unexecuted_widget.ipynb new file mode 100644 index 000000000..fca01a22a --- /dev/null +++ b/nbconvert/tests/files/Unexecuted_widget.ipynb @@ -0,0 +1,47 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "036cb3ce-96fe-4159-8145-40bb74b263f9", + "metadata": {}, + "outputs": [], + "source": [ + "import ipywidgets as widgets\n", + "widgets.IntSlider(\n", + " value=7,\n", + " min=0,\n", + " max=10,\n", + " step=1,\n", + " description='Test:',\n", + " disabled=False,\n", + " continuous_update=False,\n", + " orientation='horizontal',\n", + " readout=True,\n", + " readout_format='d'\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/nbconvert/tests/files/Unexecuted_widget_2.ipynb b/nbconvert/tests/files/Unexecuted_widget_2.ipynb new file mode 100644 index 000000000..fca01a22a --- /dev/null +++ b/nbconvert/tests/files/Unexecuted_widget_2.ipynb @@ -0,0 +1,47 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "036cb3ce-96fe-4159-8145-40bb74b263f9", + "metadata": {}, + "outputs": [], + "source": [ + "import ipywidgets as widgets\n", + "widgets.IntSlider(\n", + " value=7,\n", + " min=0,\n", + " max=10,\n", + " step=1,\n", + " description='Test:',\n", + " disabled=False,\n", + " continuous_update=False,\n", + " orientation='horizontal',\n", + " readout=True,\n", + " readout_format='d'\n", + ")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.7" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/nbconvert/tests/test_nbconvertapp.py b/nbconvert/tests/test_nbconvertapp.py index 7eac59cd6..48bc173d0 100644 --- a/nbconvert/tests/test_nbconvertapp.py +++ b/nbconvert/tests/test_nbconvertapp.py @@ -570,3 +570,29 @@ def test_widgets_from_htmlexporter(self): output, _ = HTMLExporter().from_notebook_node(nb) assert "var widgetRendererSrc = 'https://unpkg.com/@jupyter-widgets/html-manager@*/dist/embed-amd.js';" in output + + def test_execute_widgets_from_nbconvert(self): + """Check jupyter widgets render""" + notebookName = "Unexecuted_widget" + with self.create_temp_cwd([f"{notebookName}.ipynb"]): + self.nbconvert( + f"{notebookName}.ipynb --execute --log-level 0 --to html") + assert os.path.isfile(f"{notebookName}.html") + with open(f"{notebookName}.html", "r", encoding="utf8") as f: + text = f.read() + assert '