Panel + Juypter, Servers, etc.#

Panel lets you write Python code that corresponds to Javascript/HTML objects in a web browser, which requires some means of communication between the two languages. How this communication is achieved depends on the context in which Panel is used, i.e., whether it is being run in a notebook like Classic Jupyter, in JupyterLab, as a standalone web server, etc. Usually it all Just Works™, but in case it doesn’t, or if you want to understand the details or limitations of a particular configuration, this page will explain which technologies are used in which contexts to achieve the required channels of communication.

Types of communication needed:#

  1. One-time Python->JS communication: Writing Python code, emitting HTML/JS code, and running it in a browser. This is the most basic, one-way, one-time functionality involved, and is needed before any further synchronization could occur.

  2. Ongoing Python->JS synchronization: Ongoing synchronization of Python objects to JS, with Python running throughout the session and sending updates to JS property values when Python attribute values change. Necessary for dynamically updating the web page to reflect Python state.

  3. Ongoing JS->Python synchronization: Ongoing synchronization of JS objects to an ongoing Python session, with JS sending updates back to Python when the user makes selections or interacts with widgets.

Normally, any implementation with type 3 communication also has Python->JS synchronization, thus providing full JS<->Python bidirectional synchronization propagating updates in either direction as needed for full Python-backed web interfaces.

Contexts of usage:#

  • Output to HTML: Results can be emailed or put on a standard web server as an HTML file, but supports only type 1 one-time Python->JS communication, since there is no Python process running any more.

  • Notebook: Requires type 1 and 2 communication, with the user working in Python and expecting corresponding updates in JS. Ideally would also include type 3 JS->Python communication to allow capturing user selections and widget values in the browser, but that depends on the technology used.

  • Server: Typically includes all three types of communication.

Libraries/modules with support for communication in these contexts#

Here we focus on Panel objects, but this chart also applies to pure Bokeh figures and models, which have similar requirements, as well as objects built on Panel (e.g. HoloViews, GeoViews, and hvPlot objects).

Comm type

Scenario

Libraries/modules required

1

Bokeh output to .html file

bokeh (bokeh/io/output.py)

1

Bokeh used without comms support (in dash, streamlit, JupyterLite, etc.)

bokeh (bokeh/io/output.py)

1,2

Bokeh displaying in Classic Jupyter w/o Python sync

bokeh (bokeh/io/notebook.py)

1,2,3

Bokeh object in a standalone server

bokeh server (or panel serve)

1,2

Bokeh displaying in JupyterLab w/o Python sync

jupyter_bokeh

1,2,3

Bokeh object as an ipywidget

jupyter_bokeh

1,2,3

Bokeh object served in Voila

jupyter_bokeh

1,2,3

Panel object in vscode, nteract, or ipywidgets notebooks

jupyter_bokeh

1,2,3

ipywidgets in Bokeh-server apps

ipywidgets_bokeh

1,2,3

ipywidgets in Bokeh layout in Classic Jupyter

ipywidgets_bokeh

1,2,3

bidirectional Bokeh/Python syncing in Classic Jupyter

pyviz-comms

1,2,3

bidirectional Bokeh/Python syncing in JupyterLab

pyviz-comms

1,2,3

Panel object in Google colaboratory

pyviz-comms + panel (panel/viewable.py)

1,2,3

ipywidgets in Bokeh layout in JupyterLab

pyviz-comms + panel (panel/models/ipywidget.py)

1,2,3

Panel object in Pyodide/PyScript

panel (panel/io/pyodide.py)

1,2,3

Panel object in Pyodide/PyScript via Sphinx

nbsite.pyodide (& panel/io/mime_render.py)

If you find the scenario of interest to you above, you can see from the right-most column which library (or which Bokeh or Panel module) implements that functionality, and thus e.g. where to open an issue if something is not working.