papermill: ipyleaflet map is not rendered when ruhning in papermill

I have the following cell:

from IPython.display import display
from ipyleaflet import Map, Polyline

m = Map(center=(32.2, 34.8), zoom=12)
for r in df.itertuples():
    line = Polyline(
        locations=[[[r.start_latitude, r.start_longitude], [r.end_latitude, r.end_longitude]]],
        weight=15
    )
    m.add_layer(line)

display(m)

The map is displayed correctly, when running interactively. However, when running the same notebook using papermill it renders just this:

Map(basemap={'url': 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 'max_zoom': 19, 'attribution': 'Map …

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 20 (10 by maintainers)

Most upvoted comments

This should now be fixed with papermill 1.0! (I tested it with some examples from ipyleaflet github). You do need to click “Trust Notebook” from “File” after it runs to enable javascript execution.

It seems that there is confusion or misconceptions about how widgets work in the above comments. It sounds like it would be good to have some more information in the widgets docs addressing some of these points to prevent confusion.

A couple of points (and I’m happy to discuss these in more detail to try to find a good way things can work) are below.

In general the widgets are only fully supported in JupyterLab.

Widgets are fully supported in the classic notebook, and very nearly fully supported in JupyterLab (basically JLab is missing one last piece that I’m working on now - making it possible to save widget state in a notebook.)

Kernel display output for widgets not specifying the type of widget, default display information, and/or client rendering requirements. If the client needs a particular js package, it should perhaps be explicit in the output of the notebook.

In general, widgets in the client side involve two parts:

  • a model which maintains state, which is not visible, and maintained through opening a comm channel from the kernel, and exists document-wide, and
  • zero or more output display messages in cell outputs, which contain a reference to the model that should be displayed (i.e., they just contain the id of the model to display). Both pieces of information need to be saved to the document in order for a widget to display. This is what happens in https://jupyter.org/widgets and the ipywidgets docs - the widget state is saved to the notebook metadata, and the widget manager can use that and the output messages in specific cells to display widgets correctly. This widget model metadata at the notebook level essentially specifies what js package and version to use to interpret the data. Since a single model can be displayed multiple places, we chose not to copy all of this information into each output, rather having each output reference the notebook-level state.

CC also @SylvainCorlay, @maartenbreddels

Widgets which rely on user input before releasing cell execution. There should be some sort of defined behavior encoded in the kernel for headless execution (an execution without a paired js client), or perhaps the kernel should fail fast and log a message that it couldn’t satisfy the widget’s requirements for user input.

Widgets in general don’t rely on user input before releasing cell execution (actually, I don’t know of one that does do this - do you have an example?). The general model is to display the widget state as-is, and communicate changes in that state back to the kernel via kernel comm messages.

Widgets which rely on querying browser state. Either through querying specific DOM structures or earlier widget instances which hold state while the notebook is executing. In a headless execution pattern there’s no way to reliably capture these expectations.

This is a good point - probably many widget libraries assume they are running in a browser DOM, and have not been tested in a headless context. Do you have some specific examples in mind?

Binary data being transferred between the browser and kernel / other endpoints without using the kernel message protocol or an extension of such.

Binary data, as with all widget communication that I know about, uses the standardized Jupyter comm message protocol, which is part of the kernel message protocol. Do you have an example where that is not happening?

Again, I’m happy to discuss these and other points further to help. CC also @SylvainCorlay, @maartenbreddels, @pbugnion.

A few areas where I see conflicts that are hard to resolve:

  1. Kernel display output for widgets not specifying the type of widget, default display information, and/or client rendering requirements. If the client needs a particular js package, it should perhaps be explicit in the output of the notebook.
  2. Widgets which rely on user input before releasing cell execution. There should be some sort of defined behavior encoded in the kernel for headless execution (an execution without a paired js client), or perhaps the kernel should fail fast and log a message that it couldn’t satisfy the widget’s requirements for user input.
  3. Widgets which rely on querying browser state. Either through querying specific DOM structures or earlier widget instances which hold state while the notebook is executing. In a headless execution pattern there’s no way to reliably capture these expectations.
  4. Binary data being transferred between the browser and kernel / other endpoints without using the kernel message protocol or an extension of such.

There’s additional execution constraints I probably missed, but these are the ones I am aware of from assisting with the jupyter systems I’ve used or submitted code against.

Would love to hear suggestions from the more experienced Jupyter core folks for how we can support the growing ecosystem’s systems against the highly useful widgets moving forward.

Yes it is that underlying issue. However even finishing that PR won’t actually render what you expect in most front-ends.

In general the widgets are only fully supported in JupyterLab. There’s some specification gaps that prevent other systems from knowing what to provide in these cases for a front-end with an appropriate js package to render the widget state.

There’s some long-running discussions on the topic I haven’t been directly involved in. @jasongrout and @rgbkrk both have more context, but overall I think I can safely state that the display messages generated by executing widgets today rely on in-browser packages / state which backends like papermill (or nbconvert) won’t be able to populate from within the kernel protocol.

From looking through a few generations of widgets the information made available to the kernel manager varies quite a bit and many circumvent the kernel’s messaging protocol entirely. I believe this is the result of iterating the design of widgets but I think we should continue that conversation in this thread to help steer the direction of widget state in the notebook format so we can reliable populate the json document with the message outputs that front-ends which support the widget can interpret correctly.