Declarative Widget System for Jupyter Notebooks

Share: Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInShare on RedditEmail this to someonePrint this page

A very powerful feature of Jupyter Notebooks is the ability to mix interactive widgets along with your code and data. These widgets turn the Notebook into more of an Application, allowing the author to create a User Interface (UI) to the code entered in the Notebook’s cells. Rather than editing code and executing cells, the consumer of the Notebook can interact with the code by moving sliders, filling a form, pressing a button, etc.

It is very challenging to provide such a feature across the various and growing set of languages that can be hosted in a Jupyter Notebook. The work presented here aims at taking on that challenge. This is by no means complete. It is mainly a prototype built in a short amount of time and on top of many already existing pieces. We think it shows a lot of promise and would like to use it as a conversation starter. We want to work very closely with the Jupyter community in bluring the lines between a Notebook and an application.

A bit of background

The IPyWidgets project is the reference implementation of interactive widgets for the Python language. At its core, it defines a communication channel and protocol between the browser and the Python kernel. This channel is used to exchange messages between a Javascript and a Python representation of a widget. It keeps the state of the two in sync and triggers events. A user clicks on a button in the browser, a message is sent to the Python representation of the button and it performs a preconfigured action. Additionally, IPyWidgets includes a small set of widgets that are implemented and instantiated using Python, such as sliders, buttons, selections, input, and others.

WidgetModelView

IPyWidgets Diagram of Components: Image curtesy of IPyWidgets

One of the limitations of this approach is the strong tie to the language of the kernel. Originally, Jupyter/IPython was a tool built for the Python community, so it made sense to have everything done in Python. The new Jupyter project, the next incarnation of IPython, promises a language agnostic set of features, so it needs an interactive widget system that can easily be ported to many languages. IPyWidgets sets a great foundation, but you will be hard presesed to find the same level of functionality, if any, on many of the language kernels that already exist.

The work that we are about to show you attempts to remedy this situation by identifying the minimum essential pieces of IPyWidgets that need to exist in all language kernels, and building a portable layer on top that can leverage an existing and ever growing ecosystem of web widget.

Core Technologies

To start with, we are building the widget system on top of the foundation set by IPyWidgets. That means that we are leveraging the communication channel and protocol, as well as a subset of its JavaScript and Python code. We are also using Polymer and Web Components to build our elements and as a mechanism to support 3rd party offerings. The result is a declarative syntax for building the interactive areas of the Notebook that can easily connect to other code in the Notebook.

This is where we currently differ with the authoring approach of IPyWidgets (some examples). As you will see below, our widgets are instantiated using HTML, rather than with Python. Mix that with Polymer’s binding support, and it is very easy to build interactive areas with little to no JavaScript. (That is not to say that we will not have ways of building these areas using the language of the kernel, but at the moment we are assuming some Web skills.)

Lets take a look at some of the basic elements and how they can be combined to create interactivity with the Notebook code.

Interact with Functions

A very common use case is to have some code run as a side effect of interacting with UI elements. In the case of the Notebook, this code can be in the form of a function defined on a Python cell. By using our function element, the author can connect other visual elements to set the function arguments, invoke it and display its result.

Function

Click to see demonstration

Notice how we are able to use stock HTML elements to create a simple UI that allows interaction with a function defined using Python.

Working with Data

Another common use case is the use of DataFrames as the way to interact with data. Our dataframe element allows the author to refer to a Pandas or a Spark DataFrame defined with Python. This element can then be bound to other visual elements to display the data held by the DataFrame.

Demonstration of urth-core-dataframe

Click to see demonstration

The element can be set to listen to changes to the Python DataFrame and trigger notifications that change other elements that are bound to it.

A bit about data binding

We take advantage of the Polymer binding features. This enables authoring very reactive interfaces without any JavaScript. We enhance Polymer’s dom-bind extension to the template element to allow binding across separate templates created in different cells of the Notebook. This gives the author more freedom to define UI controls wherever they wish on the Notebook page, and still have the ability to bind them. Notice below how the UI generated in two different cells is able to communicate and react to changes.

Demonstration of urth-core-bind

Click to see demonstration

What about visuals and other elements?

The main advantage of this work is that it easily integrates with the ecosystem of Web Components. The example below shows some visual elements that we’ve put together as well as some from the Polymer catalog. These elements are not tied in any way to the Notebook nor its language. They basically use bindings to our core element described above to play in the Notebook space. That means that these elements are fully portable, regardless of the language used in the Notebook (i.e. Python, R, Scala, etc.).

Demonstration of urth-viz-chart

Click to see demonstration

Demonstration of urth-viz-table

Click to see demonstration

Takeaways

We hope that you appreciate the 2 main goals of this work:

  1.  Give the author a vast toolbox of components and a simple yet powerful authoring experience
  2. Minimize the effort to fully support interactive widgets on all Notebook supported languages.

This is just a start. There is still a lot of work to be done. We look forward to conversations and feedback from the community.

Share: Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInShare on RedditEmail this to someonePrint this page
Gino Bustelo

Gino Bustelo

Senior Technical Staff Member at IBM
Gino works at IBM Emerging Technologies. He enjoys learning all sorts of new technologies and building things that turn complex things into simple things. At home he is a tinkerer... getting into FPV racing quads and building Legos with the family.
Gino Bustelo
Gino Bustelo