Declarative Widget System for Jupyter Notebooks
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
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.
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.
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.
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
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.).
We hope that you appreciate the 2 main goals of this work:
- Give the author a vast toolbox of components and a simple yet powerful authoring experience
- 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.