The task is to alter the main Notebook Server page: to remove some content and add others.
The Notebook Server (as the Notebooks themselves) are Python apps, and use the Jinja Template Engine (http://jinja.pocoo.org/) for presentation, so some of this is relatively easy.
We are running Notrebook Servers in Docker Containers, therefore the changes are done using Dockerfile rather than Puppet, however the concept is easy to impliment using either system.
Tasks 1-3 are all taken care of by manipulating the template, there are three parts to this:
In jupyter_notebook_config.py, add the line
c.NotebookApp.extra_template_paths = ['/srv/templates/']
Create the ./resources/templates directory next to your Dockerfile.
In templates/, add 2 files:
{% extends "templates/page.html" %} {% block params %} {{super()}} {% endblock %} {% block header_buttons %} <span id="login_widget"></span> {% endblock %}
Add to the Dockerfile:
USER root # switches to root user, you may not need this COPY resources/templates/ /srv/templates/ RUN chmod a+rX /srv/templates
Adding a service logo can be done two ways: you can replace the Jupyter logo (there's documentation for older notebooks here) or you can add your own logo (and this add functionality to that image.) We are doing the latter.
Edit page.html :
{% block header_buttons %} <span id="login_widget"> <a href="wherever" ><img src="/custom/my-logo.png" alt="My logo" class="my-logo"></a> </span> {% endblock %}
We now need to add the graphic, and the new style class
If you look at the post Changing the location of a Notebooks configuration file you will see we are using an alternative location for our Config Dir, you may need to change things to suit your own environment.
Adding a kernel logo proved a bit trickier: we need to pass in some parameters/information to the Jinja template... and it turns out that Notebook v5.0 can do this!
In jupyter_notebook_config.py, add the line
c.NotebookApp.jinja_template_vars = {'kernel_graphic' : 'geosciences.png', 'kernel_alt_tag' : 'Geosciences Kernel'}
(the jinja_template_vars is specific, the dictionary can be whatever you want)
Copy the geosciences.png file to the jupyter/custom directory
Edit page.html to pick up the new parameters:
{% block params %} {{super()}} kernel_graphic="{{kernel_graphic}}" kernel_alt_tag="{{kernel_alt_tag}}" {% endblock %} {% block header_buttons %} <span id="login_widget"> <a href="wherever" ><img src="/custom/my-logo.png" alt="My logo" class="my-logo"></a> <img src="/custom/{{kernel_graphic}}" alt="{{kernel_alt_tag}}" class="kernel-logo"/> </span> {% endblock %}
Edit custom.css to add the kernel-logo class
One of the great features of Docker Containers is that you can base a new one on an existing one - Jupyter themselves do this: they have a base-notebook, then a minimal-notebook based off base, then base scripy- and r-notebooks off minimal.... and so on.
The catch is that we don't want to keep replacing the jupyter_notebook_config.py file each time, but extend it.
As before, we need to put our kernel logo in jupyter/custom/ directory, however we want to append to the jupyter_notebook_config.py file
Create a file called jupyter_notebook_config_extra.py in jupyter/, and set it's contents to:
c.NotebookApp.jinja_template_vars = {'kernel_graphic' : 'Rlogo.png', 'kernel_alt_tag' : 'R-language Kernel'}
(note there is a blank line at the start of this file. That blank line is important!)
Now add to the Dockerfile:
USER root # you may not need this COPY jupyter/ /etc/jupyter/ RUN cat /etc/jupyter/jupyter_notebook_config_extra.py >> /etc/jupyter/jupyter_notebook_config.py
The new Docker Image will inherit from any previous image(s), however it will set the Jinja variables to the last set in the Dockerfile.
If you don't have a blank line in the config file you append, then the chances are that the first additional line will just add to the end of the last line of the previous file, and that will almost certainly make the Dockerfile syntactically invalid.