voila Documentation

Voilà turns Jupyter notebooks into standalone web applications

5,954 stars Python Python 11 files · ~15,540 tokens #dashboarding#jupyter#jupyter-notebook#jupyterlab-extension
RAW Doc

Technical Documentation: voila-dashboards/voila

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

Overview (`README.md`)




Rendering of live Jupyter notebooks with interactive widgets.

Introduction

Voilà turns Jupyter notebooks into standalone web applications.

Unlike the usual HTML-converted notebooks, each user connecting to the Voilà
tornado application gets a dedicated Jupyter kernel which can execute the
callbacks to changes in Jupyter interactive widgets.

  • By default, Voilà disallows execute requests from the front-end, preventing
    execution of arbitrary code.
  • By default, Voilà runs with the strip_sources option, which strips out the
    input cells from the rendered notebook.

Installation

Voilà can be installed with the mamba (or conda) package manager from conda-forge

text
mamba install -c conda-forge voila

or from PyPI

text
pip install voila

JupyterLab preview extension

Voilà provides a JupyterLab extension that displays a Voilà preview of your Notebook in a side-pane.

Starting with JupyterLab 3.0, the extension is automatically installed after installing voila
with pip install voila.

If you would like to install the extension from source, run the following command.

text
jupyter labextension install @voila-dashboards/jupyterlab-preview

Usage

As a standalone tornado application

To render the bqplot example notebook as a standalone app, run
voila bqplot.ipynb.
To serve a directory of jupyter notebooks, run voila with no argument.

For example, to render the example notebook bqplot.ipynb from this repository with Voilà, you can first update your current environment with the requirements of this notebook (in this case in a conda environment and render the notebook with

text
mamba env update -f .binder/environment.yml
cd notebooks/
voila bqplot.ipynb

For more command line options (e.g., to specify an alternate port number),
run voila --help.

As a server extension to `notebook` or `jupyter_server`

Voilà can also be used as a Jupyter server extension, both with the
notebook server or with
jupyter_server.

To install the Jupyter server extension, run

text
jupyter serverextension enable voila
jupyter server extension enable voila

When running the Jupyter server, the Voilà app is accessible from the base url
suffixed with voila.

Documentation

To get started with using Voilà, check out the full documentation:

https://voila.readthedocs.io/

Examples

The following two examples show how a standalone Jupyter notebook can be turned into a separate app, from the command-line integration.

Rendering a notebook including interactive widgets and rich mime-type rendering

Rendering a notebook making use of a custom widget library ([bqplot](https://github.com/bloomberg/bqplot))

Showing the source code for a Voilà notebook

The sources of the Jupyter notebook can be displayed in a Voilà app if option strip_sources is set to False.

Voilà dashboards with other language kernels\*\*

Voilà is built upon Jupyter standard formats and protocols, and is agnostic to the programming language of the notebook. In this example, we present an example of a Voilà application powered by the C++ Jupyter kernel xeus-cpp, and the xleaflet project.

The Voilà Gallery is a collection of live dashboards and applications built with Voilà and Jupyter widgets.

Most of the examples rely on widget libraries such as ipywidgets, ipyleaflet, ipyvolume, bqplot and ipympl, and showcase how to build complex web applications entirely based on notebooks.

New examples can be added to the gallery by following the steps listed in the voila-gallery/gallery repository.

Development

See CONTRIBUTING.md to know how to contribute and set up a development environment.

Voilà depends on nbconvert and
jupyter_server.

License

We use a shared copyright model that enables all contributors to maintain the
copyright on their contributions.

This software is licensed under the BSD-3-Clause license. See the
LICENSE file for details.


Overview (`packages/jupyterlab-preview/README.md`)

@voila-dashboards/jupyterlab-preview

A JupyterLab preview extension for Voilà.

Prerequisites

  • JupyterLab 1.0+

Overview (`packages/widgets_manager7/README.md`)

@voila-dashboards/widgets-manager7

The Jupyter-widgets manager for Voilà and ipywidgets 7.


Overview (`packages/widgets_manager8/README.md`)

@voila-dashboards/widgets-manager8

The Jupyter-widgets manager for Voilà and ipywidgets 8.


Index (`docs/index.md`)

% Copyright (c) 2018, Voilà Contributors
% Copyright (c) 2018, QuantStack
%
% Distributed under the terms of the BSD 3-Clause License.
%
% The full license is in the file LICENSE, distributed with this software.

:::{note}
Want to turn your Voilà dashboard into a static webpage? Check out Voici!
The combination of JupyterLite and Voilà
:::

From notebooks to standalone web applications and dashboards.

Voilà allows you to convert a Jupyter Notebook into an
interactive dashboard that allows you to share your work with others. It
is secure and customizable, giving you control over what your readers
experience.

For example, here's a dashboard created with Voilà. (You can
try it interactively at the following Binder link)

{image} https://mybinder.org/badge_logo.svg
:target: https://mybinder.org/v2/gh/voila-dashboards/voila/stable?urlpath=voila%2Ftree%2Fnotebooks
{image} ../voila-basics.gif

Table of contents

For more information about Voilà, see the sections below.

{toctree}
:maxdepth: 2

install
using
customize
deploy
changelog
contribute

Contribute (`docs/contribute.md`)

% Copyright (c) 2018, Voilà Contributors
% Copyright (c) 2018, QuantStack
%
% Distributed under the terms of the BSD 3-Clause License.
%
% The full license is in the file LICENSE, distributed with this software.

(contribute)=

Contributing to Voilà

Voilà is a subproject of Project Jupyter and subject to the Jupyter governance and Code of conduct.

General Guidelines

For general documentation about contributing to Jupyter projects, see the Project Jupyter Contributor Documentation.

Community

The Voilà team organizes public video meetings. The schedule for future meetings and minutes of past meetings can be found on our team compass

Setting up a development environment

First, you need to fork the project. Then setup your environment:

bash
# create a new conda environment
conda create -n voila -c conda-forge notebook jupyterlab nodejs "yarn<4" pip
conda activate voila

# download voila from your GitHub fork
git clone https://github.com/<your-github-username>/voila.git

# install JS dependencies and build js assets
cd voila
yarn install

# install Voilà in editable mode
python -m pip install -e .

Run Voilà

To start Voilà, run:

bash
voila

or

bash
python -m voila

This will open a new browser tab at [http://localhost:8866/](http://localhost:8866/).

When making changes to the frontend side of Voilà, open a new terminal window and run:

bash
cd packages/voila/
npm run watch

Then reload the browser tab.

Note: the notebooks directory contains some examples that can be run with Voilà.
Checkout the instructions in the user guide
for details on how to run them.

Extensions

Server extension

To manually enable the classic notebook server extension:

bash
jupyter serverextension enable voila --sys-prefix

For Jupyter Server:

bash
jupyter server extension enable voila.server_extension --sys-prefix

This makes Voilà available as a server extension: http://localhost:8888/voila/tree.

Notebook extension

To install the notebook extension:

bash
jupyter nbextension install voila --sys-prefix --py
jupyter nbextension enable voila --sys-prefix --py

JupyterLab extension

Node.js is required and can be installed with conda:

bash
conda install -c conda-forge nodejs

The JupyterLab extension requires the server extension to be enabled. This can be done by running:

bash
jupyter serverextension enable voila --sys-prefix

You can verify if the server extension is enabled by running:

bash
jupyter serverextension list

If you use Jupyter Server:

bash
jupyter server extension enable voila --sys-prefix

You can verify if the server extension is enabled by running:

bash
jupyter server extension list

The JupyterLab extension is developed as a prebuilt extension using the new distribution system
added in JupyterLab 3.0. To setup the development environment:

bash
# install the package in development mode
python -m pip install -e .

# link your development version of the extension with JupyterLab
jupyter labextension develop . --overwrite

# build the lab extension
jlpm run build --scope @voila-dashboards/jupyterlab-preview

# it is also possible to start in watch mode to pick up changes automatically
jlpm run watch

Frontend Packages

The Voilà repository consists of several packages such as the Voilà frontend and the JupyterLab extension.

It follows a monorepo structure and uses lerna to streamline the workflow.

To build all the frontend packages at once, run the following commands:

bash
# install dependencies
jlpm

# build the packages
jlpm run build

This will run the build script in each of the packages.

Using this structure, packages can easily be linted and follow the same code style and conventions used in other Jupyter projects.
To lint the packages:

bash
# install dependencies
jlpm

# run ESLint
jlpm run eslint

# run prettier
jlpm run prettier

About the Voila Frontend

The Voila frontend is built as a JupyterLab-based application using JupyterLab components.

This makes it possible to reuse existing plugins and extensions for Jupyterlab such as core JupyterLab plugins like the JSON viewer,
as well as third-party mime renderers like the FASTA viewer.

The Voila frontend is able to load existing JupyterLab extensions installed as prebuilt extensions under ${PREFIX}/share/labextensions,
similar to the way it works in JupyterLab.

These extensions are typically distributed via pip and conda packages and can easily be installed by end users without requiring Node.js.
Widget packages usually now include a prebuilt extension for JupyterLab 3.0 by default, which should automatically work in Voila too.

Check out the JupyterLab Documentation on prebuilt extensions for more info.

The code for the frontend is located under packages/voila, with support for loading federated extensions in packages/voila/index.js.

Tests

Install the test dependencies

bash
python -m pip install -e ".[test]"

Enable the Jupyter server extension:

bash
jupyter server extension enable voila.server_extension --sys-prefix

Running the tests locally also requires the test_template and skip_template to be installed:

bash
python -m pip install ./tests/test_template ./tests/skip_template

Finally, to run the tests:

bash
python -m pytest

Editing templates

The default template files are located in the folder share/jupyter/voila/templates/default. They are automatically picked up when running Voilà in development mode.

After editing the templates, reload the browser tab to see the changes.


Customize (`docs/customize.md`)

% Copyright (c) 2018, Voilà Contributors
% Copyright (c) 2018, QuantStack
%
% Distributed under the terms of the BSD 3-Clause License.
%
% The full license is in the file LICENSE, distributed with this software.

(customize)=

Customizing Voilà

There are many ways you can customize Voilà to control the look and feel
of the dashboards you create.

Switching to the classic tree page

The default tree page of Voilà is now a JupyterLab-based application using the file browser widget.

The jinja-based tree page is still supported, but users need to activate it with the --classic-tree CLI option, the VoilaConfiguration.classic_tree config, or ?classic-tree=True in the query string, for example:

bash
voila <path-to-notebook> --classic-tree

JupyterLab custom themes are supported with the new tree page, for the classic tree page, only the light and dark themes are supported.

Changing the theme

By default, Voilà uses the light theme, but you can set the theme to dark by passing
the following option:

bash
voila <path-to-notebook> --theme=dark

Or by passing in the query parameter theme, e.g. a URL like http://localhost:8867/voila/render/query-strings.ipynb?theme=dark.

The theme can also be set in the notebook metadata, under metadata/voila/theme by editing the notebook file manually, or using the metadata editor in for instance the classical notebook

{image} metadata-theme-classic.png

System administrators who want to disable changing the theme, can pass --VoilaConfiguration.allow_theme_override=NO or
--VoilaConfiguration.allow_theme_override=NOTEBOOK to disable changing the theme completely, or only allow it from the notebook metadata.

Like nbconvert, Voilà supports the light and dark themes by default, but you can also use custom JupyterLab themes:

bash
pip install jupyterlab_miami_nights
voila <path-to-notebook> --theme="JupyterLab Miami Nights"

:::{note}
The theme argument is the theme name displayed in JupyterLab, not the name of the python package. Changing the theme from the notebook metadata may change in the future if this features moves to nbconvert.
:::

:::{warning}
Theme are specific to the "lab" template, they will not work for the "classic" template. Custom JupyterLab themes work only with the default tree page, the classic tree page supports only the light and dark theme.
:::

Controlling the nbconvert template

Voilà uses nbconvert to convert your Jupyter Notebook into an HTML dashboard.
nbconvert has a rich templating system that allows you to customize the way in
which your Jupyter Notebook is converted into HTML.

By default, Voilà will render the HTML from your notebook in the same linear fashion
that the notebook follows. If you'd like to use a different layout, this can be
controlled by creating a new nbconvert template, registering it with Voilà,
and calling it from the command-line like so:

bash
voila <path-to-notebook> --template=<name-of-template>

For example, Voilà includes one other template that uses a Javascript library and
an alternate `` layout in order to let the user drag and drop cells.

For example, to use the gridstack template, use the command:

bash
voila <path-to-notebook> --template=gridstack

Or by passing in the query parameter template, e.g. a URL like http://localhost:8867/voila/render/query-strings.ipynb?template=material (Note that this requires installing voila-material).

The template can also set in the notebook metadata, under metadata/voila/template by editing the notebook file manually, or using the metadata editor in for instance the classical notebook

{image} metadata-template-classic.png

System administrators who want to disable changing the theme, can pass --VoilaConfiguration.allow_template_override=NO` or ``--VoilaConfiguration.allow_template_override=NOTEBOOK to disable changing the theme completely, or only allow it from the notebook metadata.

:::{note}
Changing the template from the notebook metadata may change in the future if this features moves to nbconvert.
:::

:::{warning}
The "classic" template is being deprecated and its support will be removed in Voilà 1.0.0, an alternative is to use voila --template lab --show-margins to get a similar look.
:::

Creating your own template

You can create your own nbconvert template for use with Voilà. This allows you
to control the look and feel of your dashboard.

In order to create your own template, first familiarize yourself with Jinja,
HTML, and CSS. Each of these is used in creating custom templates.
For more information, see
the nbconvert templates documentation.
For one example, check out the nbconvert basic HTML template.

A few example voila/nbconvert template projects are:

Where are Voilà templates located?

All Voilà templates are stored as folders with particular configuration/template files inside.
These folders can exist in the standard Jupyter configuration locations, in a folder called voila/templates.
For example:

bash
~/.local/share/jupyter/voila/templates
~/path/to/env/dev/share/jupyter/voila/templates
/usr/local/share/jupyter/voila/templates
/usr/share/jupyter/voila/templates

Voilà will search these locations for a folder, one per template, where
the folder name defines the template name.

The Voilà template structure

Within each template folder, you can provide your own nbconvert templates, static
files, and HTML templates (for pages such as a 404 error). For example, here is
the folder structure of the base Voilà template (called "default"):

bash
tree path/to/env/share/jupyter/voila/templates/default/
├── nbconvert_templates
│   ├── base.tpl
│   └── voila.tpl
└── templates
    ├── 404.html
    ├── error.html
    ├── page.html
    └── tree.html

To customize the nbconvert template, store it in a folder called templatename/nbconvert_templates/voila.tpl.
In the case of the default template, we also provide a base.tpl that our custom template uses as a base.
The name voila.tpl is special - you cannot name your custom nbconvert something else.

To customize the HTML page templates, store them in a folder called templatename/templates/<name>.html.
These are files that Voilà can serve as standalone HTML (for example, the tree.html template defines how
folders/files are displayed in localhost:8866/voila/tree). You can override the defaults by providing your
own HTML files of the same name.

To configure your Voilà template, you should add a config.json file to the root of your template
folder.

:::{warning}
Custom tree page templates work only with the classic tree page.
:::

% todo: Add information on config.json

An example custom template

To show how to create your own custom template, let's create our own nbconvert template.
We'll have two goals:

  1. Add an <h1> header displaying "Our awesome template" to the Voilà dashboard.
  2. Add a custom 404.html page that displays an image.

First, we'll create a folder in ~/.local/share/jupyter/voila/templates called mytemplate:

text
mkdir ~/.local/share/jupyter/voila/templates/mytemplate
cd ~/.local/share/jupyter/voila/templates/mytemplate

Next, we'll copy over the base template files for Voilà, which we'll modify:

text
cp -r path/to/env/share/jupyter/voila/templates/default/nbconvert_templates ./
cp -r path/to/env/share/jupyter/voila/templates/default/templates ./

We should now have a folder structure like this:

bash
tree .
├── nbconvert_templates
│   ├── base.tpl
│   └── voila.tpl
└── templates
    ├── 404.html
    ├── error.html
    ├── page.html
    └── tree.html

Now, we'll edit nbconvert_templates/voila.tpl to include a custom H1 header.

As well as templates/tree.html to include an image.

Finally, we can tell Voilà to use this custom template the next time we use it on
a Jupyter notebook by using the name of the folder in the --template parameter:

text
voila mynotebook.ipynb --template=mytemplate

The result should be a Voilà dashboard with your custom modifications made!

Voilà template cookiecutter

There is a Voilà template cookiecutter available to give you a running start.
This cookiecutter contains some docker configuration for live reloading of your template changes to make development easier.
Please refer to the cookiecutter repo for more information on how to use the Voilà template cookiecutter.

Customizing Voila with Hooks

Voila provides hooks that allow you to customize its behavior to fit your specific needs. These hooks enable you to inject custom functions at certain points during Voila's execution, giving you control over aspects like notebook execution and frontend configuration.

Currently, Voila supports the following hooks:

  • prelaunch_hook: Access and modify the Tornado request and notebook before execution.
  • page_config_hook: Customize the page_config object, which controls the Voila frontend configuration.

Accessing the tornado request (`prelaunch-hook`)

In certain custom setups when you need to access the tornado request object in order to check for authentication cookies, access details about the request headers, or modify the notebook before rendering. You can leverage the prelaunch-hook, which lets you inject a function to inspect the notebook and the request prior to executing them.

:::{warning}
Because prelaunch-hook only runs after receiving a new request but before the notebook is executed, it is incompatible with
preheated kernels.
:::

Creating a hook function

The format of this hook should be:

python
def prelaunch_hook(req: tornado.web.RequestHandler,
         notebook: nbformat.NotebookNode,
         cwd: str) -> Optional[nbformat.NotebookNode]:
  • The first argument will be a reference to the tornado RequestHandler, with which you can inspect parameters, headers, etc.
  • The second argument will be the NotebookNode, which you can mutate to e.g. inject cells or make other notebook-level modifications.
  • The last argument is the current working directory should you need to mutate anything on disk.
  • The return value of your hook function can either be None, or a NotebookNode.

Customize the page config object (`page_config_hook`)

The page_config_hook allows you to customize the page_config object, which controls various aspects of the Voila frontend. This is useful when you need to modify frontend settings such as the URLs for static assets or other configuration parameters.

By default, Voila uses the following page_config:

python
# Default page_config
page_config = {
    "appVersion": __version__,
    "appUrl": "voila/",
    "themesUrl": "/voila/api/themes",
    "baseUrl": base_url,
    "terminalsAvailable": False,
    "fullStaticUrl": url_path_join(base_url, "voila/static"),
    "fullLabextensionsUrl": url_path_join(base_url, "voila/labextensions"),
    "extensionConfig": voila_configuration.extension_config,
}

The format of this hook should be:

python
def page_config_hook(
      current_page_config: Dict[str, Any],
      base_url: str,
      settings: Dict[str, Any],
      log: Logger,
      voila_configuration: VoilaConfiguration,
      notebook_path: str
) -> Dict[str, Any]:

Adding the hook function to Voilà

There are two ways to add the hook function to Voilà:

  • Using the voila.py configuration file:

Here is an example of the configuration file. This file needs to be placed in the directory where you start Voilà.

python
def prelaunch_hook_function(req, notebook, cwd):
   """Do your stuffs here"""
   return notebook

def page_config_hook_function(current_page_config, **kwargs):
   """Modify the current_page_config"""
   return new_page_config

c.VoilaConfiguration.prelaunch_hook = hook_function
c.VoilaConfiguration.page_config_hook = page_config_hook
  • Start Voilà from a python script:

Here is an example of a custom prelaunch-hook to execute a notebook with papermill, and a page_config_hook to add a custom labextensions URL:

python
def parameterize_with_papermill(req, notebook, cwd):
    import tornado

    # Grab parameters
    parameters = req.get_argument("parameters", {})

    # try to convert to dict if not e.g. string/unicode
    if not isinstance(parameters, dict):
        try:
            parameters = tornado.escape.json_decode(parameters)
        except ValueError:
            parameters = None

    # if passed and a dict, use papermill to inject parameters
    if parameters and isinstance(parameters, dict):
        from papermill.parameterize import parameterize_notebook

        # setup for papermill
        #
        # these two blocks are done
        # to avoid triggering errors
        # in papermill's notebook
        # loading logic
        for cell in notebook.cells:
            if 'tags' not in cell.metadata:
                cell.metadata.tags = []
            if "papermill" not in notebook.metadata:
                notebook.metadata.papermill = {}

        # Parameterize with papermill
        return parameterize_notebook(notebook, parameters)


def page_config_hook(
   current_page_config: Dict[str, Any],
   base_url: str,
   settings: Dict[str, Any],
   log: Logger,
   voila_configuration: VoilaConfiguration,
   notebook_path: str
):
    page_config['fullLabextensionsUrl'] = '/custom/labextensions_url'
    return page_config

You can use both hooks simultaneously to customize notebook execution and frontend configuration, to add this hooks to your Voilà application:

python
from voila.app import Voila
from voila.config import VoilaConfiguration

# customize config how you like
config = VoilaConfiguration()

# set the prelaunch hook
config.prelaunch_hook = parameterize_with_papermill

# set the page config hook
config.page_config_hook = page_config_hook

# create a voila instance
app = Voila()

# set the config
app.voila_configuration = config

# launch
app.start()

Adding your own static files

If you create your own theme, you may also want to define and use your
own static files, such as CSS and Javascript. To use your own static files,
follow these steps:

  1. Create a folder along with your template (e.g., mytemplate/static/).

  2. Put your static files in this template.

  3. In your template file (e.g. voila.tpl), link these static files with
    the following path:

    text
    {{resources.base_url}}voila/static/<path-to-static-files>
  4. When you call voila, configure the static folder by using the
    --static kwarg, or by configuring --VoilaConfiguration.static_root.

Any folders / files that are inside the folder given with this configuration
will be copied to {{resources.base_url}}voila/static/.

For example, if you had a CSS file called custom.css in static/css,
you would link it in your template like so:

text
<link rel="stylesheet" type="text/css" href="{{resources.base_url}}voila/static/css/custom.css"></link>

Configure Voilà for the Jupyter Server

Several pieces of voila's functionality can be controlled when it is
run. This can be done either as a part of the standalone CLI, or with the
Jupyter Server. To configure voila when run by the Jupyter Server,
use the following pattern when invoking the command that runs Jupyter (e.g.,
Jupyter Lab or Jupyter Notebook):

text
<jupyter-command> --VoilaConfiguration.<config-key>=<config-value>

For example, to control the template used by voila from within a Jupyter
Lab session, use the following command when starting the server:

text
jupyter lab --VoilaConfiguration.template=distill

When users run voila by hitting the voila/ endpoint, this configuration
will be used.

Activating token authentication

By using jupyter-server 2, Voilà supports token authentication, but it is disabled by default.

  • To start Voila with auto-generated token:
text
voila --token notebook.ipynb
  • To start Voila with a personalized token:
text
voila --token=my-secret-token notebook.ipynb

Serving static files

Unlike JupyterLab or the classic notebook server, voila does not serve
all files that are present in the directory of the notebook. Only files that
match one of the allowlist and none of the denylist regular expression are
served by Voilà:

text
voila mydir --VoilaConfiguration.file_allowlist="['.*']" \
  --VoilaConfiguration.file_denylist="['private.*', '.*\.(ipynb)']"

Which will serve all files, except anything starting with private, or notebook files:

text
voila mydir --VoilaConfiguration.file_allowlist="['.*\.(png|jpg|gif|svg|mp4|avi|ogg)']"

Will serve many media files, and also never serve notebook files (which is the default denylist).

Run scripts

Voilà can run text (or script) files, by configuring how a file extension maps to a kernel language:

text
voila mydir --VoilaConfiguration.extension_language_mapping='{".py": "python", ".jl": "julia"}'

Voilà will find a kernel that matches the language specified, but can also be
configured to use a specific kernel for each language:

text
voila mydir --VoilaConfiguration.extension_language_mapping='{".py": "python", ".jl": "julia"}'\
  --VoilaConfiguration.language_kernel_mapping='{"python": "xpython"}'

In this case it will use the xeus-python. kernel to run .py files.

Note that the script will be executed as notebook with a single cell, meaning
that only the last expression will be printed as output. Use the Jupyter
display mechanism to output any text or rich output such as Jupyter widgets. For
Python this would be a call to IPython.display.display.

Using Jupytext is another way to support
script files. After installing jupytext, Voilà will see script files as if they
are notebooks, and requires no extra configuration.

Cull idle kernels

Voilà starts a new Jupyter kernel every time a notebook is rendered to the user. In some situations, this can lead to a higher memory consumption.

The Jupyter Server exposes several options that can be used to terminate kernels that are not active anymore. They can be configured using the Voilà standalone app:

bash
voila --MappingKernelManager.cull_interval=60 --MappingKernelManager.cull_idle_timeout=120

The server will periodically check for idle kernels, in this example every 60 seconds, and cull them if they have been idle for more than 120 seconds.

The same parameters apply when using Voilà as a server extension:

bash
jupyter notebook --MappingKernelManager.cull_interval=60 --MappingKernelManager.cull_idle_timeout=120

There is also the MappingKernelManager.cull_busy and MappingKernelManager.cull_connected options to cull busy kernels and kernels with an active connection.

For more information about these options, check out the Jupyter Server documentation.

Preheated kernels

Since Voilà needs to start a new jupyter kernel and execute the requested notebook in this kernel for every connection, this would lead to a long waiting time before the widgets can be displayed in the browser.
To reduce this waiting time, especially for heavy notebooks, users can activate the preheating kernel option of Voilà.

:::{warning}
Because preheated kernels are not executed on request, this feature is incompatible with the prelaunch-hook functionality.
:::

This option will enable two features:

  • A pool of kernels is started for each notebook and kept in standby, then the notebook is executed in every kernel of its pool. When a new client requests a kernel, the preheated kernel in this pool is used and another kernel is started asynchronously to refill the pool.
  • The HTML version of the notebook is rendered in each preheated kernel and stored, when a client connects to Voilà, under some conditions, the cached HTML is served instead of re-rendering the notebook.

The preheating kernel option works with any kernel manager, it is deactivated by default, re-activate it by setting preheat_kernel = True. For example, with this command, for each notebook Voilà started with, a pool of 5 kernels is created and will be used for new connections.

bash
voila --preheat_kernel=True --pool_size=5

The default environment variables for preheated kernels can be set by the VoilaKernelManager.default_env_variables setting. For example, this command

bash
voila --preheat_kernel=True --VoilaKernelManager.default_env_variables='{"FOO": "BAR"}'

will set the variable "FOO" in all preheated kernels.

If the pool size does not match the user's requirements, or some notebooks need to use specific environment variables..., additional settings are needed. The easiest way to change these settings is to provide a file named voila.json in the directory where you start Voilà. Settings for preheating kernel ( list of notebooks does not need preheated kernels, number of kernels in pool, refilling delay, environment variables for starting kernel...) can be set under the VoilaKernelManager class name.

Here is an example of settings with explanations for preheating kernel option.

python
# voila.json
{
   "VoilaConfiguration": {
      # Activate or deactivate preheat kernel option.
      "preheat_kernel": true
   },
   "VoilaKernelManager": {
      # A list of notebook name or regex patterns to exclude notebooks from using preheat kernel.
      "preheat_denylist": [
         "notebook-does-not-need-preheat.ipynb",
         "^.*foo.*$",
         ...
      ],
      # Configuration for kernel pools
      "kernel_pools_config": {
         # Setting for `voila.ipynb` notebook
         "voila.ipynb": {
            "pool_size": 3, # Size of pool
            "kernel_env_variables": { # The environment variables used to start kernel for `voila.ipynb`
               "foo2": "bar2"
            }
         },
         # Setting for `test/sub-voila.ipynb` notebook
         "test/sub-voila.ipynb": {
            "pool_size": 1
         },
         ...
         # If a notebook does not have setting, it will use default setting
         "default": {
            "pool_size": 2,
            "kernel_env_variables": {
               "foo": "bar"
            }
         },
      },
      # Delay time in second before filling the kernel pool.
      "fill_delay": 0
   }
}

Notebook HTML will be pre-rendered with template and theme defined in VoilaConfiguration or notebook metadata. The preheated kernel and cached HTML are used if these conditions are matched:

  • There is an available preheated kernel in the kernel pool.
  • If user overrides the template/theme with query string, it must match the template/theme used to pre-render the notebook.

If the kernel pool is empty or the request does not match these conditions, Voilà will fail back to start a normal kernel and render the notebook as usual.

Partially pre-render notebook

To benefit the acceleration of preheating kernel mode, the notebooks need to be pre-rendered before users actually connect to Voilà. But in many real-world cases, the notebook requires some user-specific data to render correctly the widgets, which makes pre-rendering impossible. To overcome this limit, Voilà offers a feature to treat the most used method for providing user data: the URL query string.

:::{note}
For more advanced interaction with the tornado request object, see the prelaunch-hook feature.
:::

In normal mode, Voilà users can get the query string at run time through the QUERY_STRING environment variable:

python
import os
query_string = os.getenv('QUERY_STRING')

In preheating kernel mode, users can prepend with wait_for_request from voila.utils

python
import os
from voila.utils import wait_for_request
wait_for_request()
query_string = os.getenv('QUERY_STRING')

wait_for_request will pause the execution of the notebook in the preheated kernel at this cell and wait for an actual user to connect to Voilà, set the request info environment variables and then continue the execution of the remaining cells.

If the Voilà websocket handler is not started with the default protocol (ws), the default IP address (127.0.0.1) the default port (8866) or with url suffix, users need to provide these values through the environment variables VOILA_WS_PROTOCOL, VOILA_APP_IP, VOILA_APP_PORT and VOILA_WS_BASE_URL. One way to set these variables is in the voila.json configuration file, for example:

python
# voila.json
{
   ...
   "VoilaKernelManager": {
      "kernel_pools_config": {
         "foo.ipynb": {
            "kernel_env_variables": {
               "VOILA_APP_IP": "192.168.1.1",
               "VOILA_APP_PORT": "6789",
               "VOILA_WS_PROTOCOL": "wss"
            }
         }
      },
   ...
   }
}

Additionally, you can set these with the command:

bash
voila --preheat_kernel=True --VoilaKernelManager.default_env_variables='{"VOILA_WS_PROTOCOL":"wss","VOILA_APP_IP":"192.168.1.1"}'

Hiding output and code cells based on cell tags

Voilà uses nbconvert under the hood to render the notebooks so we can benefit from some of its advanced functionalities to hide code and output cells based on cell tags.

To hide the cell output for every cell in your notebook that has been tagged (how to tag) with "hide" in Voilà:

text
voila --TagRemovePreprocessor.remove_all_outputs_tags='{"hide"}' your_notebook.ipynb

To hide both the code cell and the output cell (if any) for every cell that has been tagged with "hide":

text
voila --TagRemovePreprocessor.remove_cell_tags='{"hide"}' your_notebook.ipynb

You can use any tag you want but be sure to use the same tag name in the Voilà command.
And please note that this functionality will only hide the cells in Voilà but will not prevent them from being executed.

Cell execution timeouts

By default, Voilà does not have an execution timeout, meaning there is no limit for how long it takes for Voilà to execute and render your notebook. If you have potentially long-running cells, you may wish to set a cell execution timeout so that users of your dashboard will get an error if it takes longer than expected to execute the notebook. For example:

bash
voila --VoilaExecutor.timeout=30 your_notebook.ipynb

With this setting, if any cell takes longer than 30 seconds to run, a TimeoutError will be raised. You can further customize this behavior using the VoilaExecutor.timeout_func and VoilaExecutor.interrupt_on_timeout options.

Customizing the Voilà Preview widget

By using the layout customization system of JupyterLab, users can configure the position of the Voilà preview widget to open it in a different area than main.

Voila Preview is the setting key of the preview widget. For example, the following configuration will open this widget in the right panel of JupyterLab

javascript
"layout": {
   "multiple": {
      "Voila Preview": { "area": "right" }
   }
}

Custom kernel_spec_manager class

By default, Voilà uses jupyter_client's KernelSpecManager. To change this class, add the following to your config like so:

py
import CustomKernelSpecManager

c.VoilaConfiguration.kernel_spec_manager_class = CustomKernelSpecManager

Kernel startup_timeout

By default, Voilà's grace period for kernel startup time is 60 seconds. It can be adjusted as such, in seconds

sh
voila --VoilaExecutor.startup_timeout=60

Have voila attempt to solve a best fit kernel spec

By default, Voilà will attempt to resolve a kernel spec to the best fit, based on the available environments. You can disable this functionality as follows:

py
c.VoilaConfiguration.attempt_fix_notebook = False

Changing dashboard rendering technique

There are two dashboard rendering techniques in Voilà:

  • Blocking rendering (default): In this method, Voilà completes the execution of the entire notebook before displaying the dashboard. It is ideal for lightweight notebooks, as a loading spinner is shown until execution finishes..
  • Progressive rendering (introduced in Voilà 0.6): With this method, the dashboard appears immediately, with placeholders filling the cell outputs. These outputs are updated as each cell is executed by the kernel.

To start Voilà with progressive rendering mode using CLI:

bash
voila ... --progressive_rendering=True

or using voila.json file

python
# voila.json
{
   ...
   "VoilaConfiguration": {
      "progressive_rendering": true,
      ...
   }
}

:::{warning}
Progressive rendering mode is incompatible with the preheated kernels functionality.
:::

Custom labextension for Voila

Since Voila 0.5.0, it can now load JupyterLab extensions. Allowing to load custom mimetype extensions, JupyterLab themes etc.

Voila will load all extensions under {PREFIX}/share/jupyter/labextensions just like JupyterLab and Jupyter Notebook v7.

It also has its own path for labextensions that you can use: {PREFIX}/share/jupyter/voila/labextensions. Installing extensions there will make those extensions only available to Voila. This is really useful if you
don't want to pollute JupyterLab or Jupyter Notebook with extensions that only work for Voila.

Configuring extra labextensions paths

You can configure additional paths for Voilà to search for JupyterLab extensions using the extra_labextensions_path configuration option:

bash
voila --VoilaConfiguration.extra_labextensions_path="['/path/to/custom/extensions', '/another/path']"

Or via the configuration file (voila.json):

json
{
  "VoilaConfiguration": {
    "extra_labextensions_path": ["/path/to/custom/extensions", "/another/path"]
  }
}

Or in a Python configuration file (voila.py):

python
c.VoilaConfiguration.extra_labextensions_path = [
    '/path/to/custom/extensions',
    '/another/path'
]

:::{note}
The extra_labextensions_path directories are prepended to the default labextensions_path. In other words, extensions in the extra_labextensions_path will take precedence over those in the standard locations.
:::


Deploy (`docs/deploy.md`)

% Copyright (c) 2018, Voilà Contributors
% Copyright (c) 2018, QuantStack
%
% Distributed under the terms of the BSD 3-Clause License.
%
% The full license is in the file LICENSE, distributed with this software.

Deploying Voilà

The deployment docs are split up in two parts. First there is the
general section, which should always be followed. Then there is a cloud
service provider specific section of which one provider should be chosen.

If you are not sure where to deploy your app, we suggest Binder or Heroku. You can test
deploying and serving your app without having to enter any credit card details,
and with very little prior experience of deployments.

Setup an example project

  1. Create a project directory of notebooks you wish to display. For this
    tutorial we will clone Voilà and treat the notebooks folder as our
    project root.

    bash
    git clone [email protected]:voila-dashboards/voila.git
    cd voila/notebooks/
  2. Add a requirements.txt file to the project directory. This file should
    contain all the Python dependencies your Voilà app needs to run. For this
    tutorial we will copy the contents of the environment.yml of Voilà.
    We omit xleaflet and xeus-cpp because these require extra work that is
    beyond the scope of this guide.

    text
    bqplot
    ipympl
    ipyvolume
    scipy
    voila

Cloud Service Providers

Deployment on Binder

Binder is one of the most accessible ways to deploy Voilà applications.
The service is available at mybinder.org and is increasingly
being used for reproducible research, making it an excellent fit for deploying Voilà applications.

  1. Make sure the repository is publicly available (on GitHub, Gitlab or as a gist).
  2. Follow this guide
    to prepare the repository. For simple deployments, steps listed in [Setup an example project] will be sufficient.

:::{note}
Binder also supports environment.yml files and conda environments.
:::

  1. Go to mybinder.org and enter the URL of the repository.
  2. In Path to a notebook file, select URL and use the Voilà endpoint: voila/render/path/to/notebook.ipynb
  3. Click Launch.
  4. Binder will trigger a new build if this is the first launch (or if there has been new changes since
    the last build). This might take a few minutes to complete. If an image is already available,
    the server will be able to start within a few seconds.

Customizing Voilà on Binder

To specify different options (such as the theme and template), create a
jupyter_config.json file at the root of the repository with the following content:

json
{
  "VoilaConfiguration": {
    "theme": "dark",
    "template": "gridstack"
  }
}

An example can be found in the
voila-demo repository.

Deployment on Ploomber Cloud

Ploomber Cloud offers a free deployment option for
Voilà apps. Once you create an account and log in, follow these steps:

  1. Click on the "NEW" button
  2. In the "Framework" section, click on Voilà
  3. In the "Source code" section, click on "Upload your files"
  4. Upload your .ipynb file and requirements.txt file
  5. Click on "CREATE"
  6. Wait until deployment finishes. To see your app, click on the "VIEW" button

Full instructions for deploying Voilà apps are available here.

Deployment on Railway

:::{note}
Heroku.com was the suggested option for free deployment but since November 28th 2022, free
product plans have been removed from the platform. The process described in
this section remain valid for other services.
:::

Railway.app is an attractive option if you want to try
out deployment for free. You have limited computing hours, however the app will
also automatically shutdown if it is idle.

From the template

You can just press this button to make your own deployment from the available template. This will create a fork of the Github template
that you can then fill with your Notebooks and dependencies:

Manually

The general steps for deployment at Railway can be found
here.
High level instructions, specific to Voilà can be found below:

  1. Follow the steps of the official documentation to install the Railway
    CLI and login on your machine.

  2. Add a file named runtime.txt to the project directory with a
    valid Python runtime:

    text
    python-3.10.4
  3. Add a file named Procfile to the project directory with the
    following content if you want to show all notebooks:

    text
    web: voila --port=$PORT --no-browser --Voila.ip=0.0.0.0

    Or the following if you only want to show one notebook:

    text
    web: voila --port=$PORT --no-browser --Voila.ip=0.0.0.0 your_notebook.ipynb
  4. Initialize a git repo and commit your code. At minimum you need to commit
    your notebooks, requirements.txt, runtime.txt, and the Procfile.

    bash
    git init
    git add <your-files>
    git commit -m "my message"
  5. Create an Railway instance and push the code.

    bash
    railway init
  6. Open your web app

    bash
    railway up --detach

To resolve issues, it is useful to see the logs of your application. You can do this by running:

bash
railway up

Deployment on Google App Engine

You can deploy on Google App
Engine
in a “flexible”
environment. This means that the underlying machine will always run.
This is more expensive than a “standard” environment, which is similar
to Heroku’s free option. However, Google App Engine’s “standard”
environment does not support websockets, which is a requirement for
voila.

The general steps for deployment at Google App Engine can be found
here.
High level instructions specific to Voilà can be found below:

  1. Follow the “Before you begin steps” from the official documentation
    to create your account, project and App Engine app.

  2. Add an app.yaml file to the project directory with the following content:

    yaml
    runtime: python
    env: flex
    runtime_config:
      python_version: 3
    entrypoint: voila --port=$PORT --Voila.ip=0.0.0.0 --no-browser
  3. Edit the last line if you want to show only one notebook

    yaml
    entrypoint: voila --port=$PORT --Voila.ip=0.0.0.0 --no-browser your_notebook.ipynb
  4. Deploy your app

    bash
    gcloud app deploy
  5. Open your app

    bash
    gcloud app browse

Deployment on Hugging Face Spaces

You can follow the instruction from here to deploy Voila dashboards to Hugging Face Spaces

Running Voilà on a private server

Prerequisites

  • A server running Ubuntu 18.04 (or later) with root access.
  • Ability to SSH into the server and run commands from the prompt.
  • The public IP address of the server.
  • A domain name pointing to the IP address of the server.

Steps

  1. SSH into the server:

    text
    ssh ubuntu@<ip-address>
  2. Install nginx:

    text
    sudo apt install nginx
  3. To check that nginx is correctly installed:

    text
    sudo systemctl status nginx
  4. Create the file /etc/nginx/sites-enabled/yourdomain.com with the following content:

    text
    server {
        listen 80;
        server_name yourdomain.com;
        proxy_buffering off;
        location / {
            proxy_pass http://localhost:8866;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_read_timeout 86400;
        }
    
        client_max_body_size 100M;
        error_log /var/log/nginx/error.log;
    }
  5. Enable and start the nginx service:

    text
    sudo systemctl enable nginx.service
    sudo systemctl start nginx.service
  6. Install pip:

    text
    sudo apt update && sudo apt install python3-pip
  7. Follow the instructions in [Setup an example project], and install the dependencies:

    text
    sudo python3 -m pip install -r requirements.txt
  8. Create a new systemd service for running Voilà in /usr/lib/systemd/system/voila.service. The service will ensure Voilà is automatically restarted on startup:

    text
    [Unit]
    Description=Voila
    
    [Service]
    Type=simple
    PIDFile=/run/voila.pid
    ExecStart=voila --no-browser voila/notebooks/basics.ipynb
    User=ubuntu
    WorkingDirectory=/home/ubuntu/
    Restart=always
    RestartSec=10
    
    [Install]
    WantedBy=multi-user.target

In this example Voilà is started with voila --no-browser voila/notebooks/basics.ipynb to serve a single notebook.
You can edit the command to change this behavior and the notebooks Voilà is serving.

  1. Enable and start the voila service:

    text
    sudo systemctl enable voila.service
    sudo systemctl start voila.service

:::{note}
To check the logs for Voilà:

text
journalctl -u voila.service

:::

  1. Now go to yourdomain.com to access the Voilà application.

Enable HTTPS with Let's Encrypt

  1. Install certbot:

    text
    sudo add-apt-repository ppa:certbot/certbot
    sudo apt update
    sudo apt install python-certbot-nginx
  2. Obtain the certificates from Let's Encrypt. The --nginx flag will edit the nginx configuration automatically:

    text
    sudo certbot --nginx -d yourdomain.com
  3. /etc/nginx/sites-enabled/yourdomain.com should now contain a few more entries:

    text
    $ cat /etc/nginx/sites-enabled/yourdomain.com
    
    ...
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    ...
  4. Visit yourdomain.com to access the Voilà applications over HTTPS.

  5. To automatically renew the certificates (they expire after 90 days), open the crontab file:

    text
    crontab -e

    And add the following line:

    text
    0 12 * * * /usr/bin/certbot renew --quiet

For more information, you can also follow the guide on the nginx blog.

Using Apache2 as reverse proxy

Apache can also be used to serve voilà. These Apache modules need to be installed and enabled:

  • mod_proxy
  • mod_rewrite
  • mod_proxy_http
  • mod_proxy_wstunnel

With the following configuration:

text
<VirtualHost *:443>
   # ...
   ProxyRequests Off
   ProxyPreserveHost Off

   <LocationMatch  "/voila/">
      RewriteEngine on
      RewriteCond %{REQUEST_URI} /voila/api/kernels/
      RewriteRule .*/voila/(.*) "ws://127.0.0.1:50001/voila/$1" [P,L]
      ProxyPreserveHost On
      ProxyPass http://127.0.0.1:50001/voila/
      ProxyPassReverse  http://127.0.0.1:50001/voila/
   </LocationMatch>
</VirtualHost>

For the record, Voila was instanciated with the following command line:

text
$ voila --autoreload=True --port=50001 --base_url=/voila/

And clients can access the instance using https://myhost/voila/

Sharing Voilà applications with ngrok

ngrok is a useful tool to expose local servers to the public internet over secure tunnels.
It can be used to share Voilà applications served by a local instance of Voilà.

The main use case for using Voilà with ngrok is to quickly share a notebook as an interactive application without
having to deploy to external hosting.

:::{warning}
Don't forget to exercise caution before exposing local apps and data to the public over the internet.

While Voilà does not permit arbitrary code execution, be aware that sensitive information could be exposed,
depending on the content and the logic of the notebook.

It's good practice to keep the ngrok tunnel connection short-lived, and limit its use to quick sharing purposes.
:::

Setup ngrok

To setup ngrok, follow the Download and setup ngrok guide.

Sharing Voilà applications

  1. Start Voilà locally: voila --no-browser my_notebook.ipynb
  2. In a new terminal window, start ngrok: ngrok http 8866
  3. Copy the link from the ngrok terminal window. The links looks like the following: 8bb6fded.ngrok.io
  4. Send the link
  5. When using the ngrok link, the requests will be forwarded to your local instance of Voilà.

Environment.Yml (`docs/environment.yml`)

name: voila
channels:

  • conda-forge
  • conda
    dependencies:
  • myst-parser
  • nodejs
  • jupyterlab=4.5
  • sphinx
  • pydata-sphinx-theme
  • pip:
    • sphinxcontrib-video
    • ..

Install (`docs/install.md`)

% Copyright (c) 2018, Voilà Contributors
% Copyright (c) 2018, QuantStack
%
% Distributed under the terms of the BSD 3-Clause License.
%
% The full license is in the file LICENSE, distributed with this software.

(install)=

Installing Voilà

Voilà can be installed with the mamba or conda package manager

bash
mamba install -c conda-forge voila

or from PyPI:

bash
pip install voila

Once Voilà is installed, it can be used either as a Command-Line Interface,
or as a Jupyter Server extension. See {ref}using for information on how to use Voilà.


Using (`docs/using.md`)

% Copyright (c) 2018, Voilà Contributors
% Copyright (c) 2018, QuantStack
%
% Distributed under the terms of the BSD 3-Clause License.
%
% The full license is in the file LICENSE, distributed with this software.

(using)=

Using Voilà

Voilà can be used as a standalone application, or as a Jupyter server
extension. This page describes how to do each. Before you begin, make
sure that you follow the steps in {ref}install.

The following sections cover how to use Voilà.

As a standalone application

Voilà can be used to run, convert, and serve a Jupyter notebook as a
standalone app. This can be done via the command-line, with the following
pattern:

bash
voila <path-to-notebook> <options>

For example, to render the bqplot example notebook as a standalone app, run

bash
git clone https://github.com/voila-dashboards/voila
cd voila
voila notebooks/bqplot.ipynb

Voilà displays a message when your notebook-based application is live.
By default, Voilà runs at localhost:8866.

To serve a directory of Jupyter Notebooks, navigate to the directory
you'd like to serve, then simply run voila:

bash
cd notebooks/
voila

The page served by Voilà will now contain a list of any notebooks in the
directory. By clicking on one, you will trigger Voilà's conversion process.
A new Jupyter kernel will be created for each notebook you click.

As a Jupyter server extension

You can also use Voilà from within a Jupyter server (e.g., after running
jupyter lab or jupyter notebook).

:::{note}
Voilà can also be used as a notebook server extension, both with the
notebook server or with the
jupyter_server.
:::

To use Voilà within a pre-existing Jupyter server, first start the server,
then go to the following URL:

bash
<url-of-my-server>/voila

For example, if you typed jupyter lab and it was running at
http://localhost:8888/lab, then Voilà would be accessed at
http://localhost:8888/voila.

In this case, Voilà will serve the directory in which the Jupyter
server was started.

How does Voilà work?

When Voilà is run on a notebook, the following steps occur:

  1. Voilà runs the code in the notebook and collects the outputs
  2. The notebook and its outputs are converted to HTML. By default,
    the notebook code cells are hidden.
  3. This page is served either as a Tornado application, or via the
    Jupyter server.
  4. When users access the page, the widgets on the page have access to
    the underlying Jupyter kernel.

The example notebooks

The notebooks directory
contains a collection of Jupyter notebooks that can be rendered using Voilà:

  • basics.ipynb - a notebook with interactions requiring a roundtrip to the kernel.
  • bqplot.ipynb - uses custom Jupyter widgets such as
    bqplot.
  • dashboard.ipynb - uses gridstack.js for the layout of each output.
  • gridspecLayout.ipynb - uses
    GridspecLayout
    for the layout of different widgets.
  • interactive.ipynb - makes use of ipywidget's @interact.
  • ipympl.ipynb - contains custom interactive matplotlib figures using the
    ipympl widget.
  • ipyvolume.ipynb - uses custom Jupyter widgets such as
    ipyvolume.
  • query-strings.ipynb - uses HTTP query parameters to parametrize a notebook
  • xleaflet.ipynb - a notebook that uses C++ kernel and interactive widgets

These examples demonstrate different interactive HTML widgets and can be used as inspiration
for getting started with Voilà.

To run the example notebooks, a few additional libraries can be installed using:

bash
conda install -c conda-forge ipywidgets ipyvolume bqplot scipy

Or alternatively:

bash
conda env create

The examples can then be served with:

bash
cd notebooks/
voila

--- METRICS ---