[Debian-science-sagemath] How to deal with jupyter notebook extensions

Ximin Luo infinity0 at debian.org
Sat Dec 3 16:07:00 UTC 2016


+debian-python@

Jupyter Notebook allows for the installation of "extensions". Users typically download an extension, then run something like this:

$ jupyter nbextension install <package>  # or python/python3 -m notebook.extension install [..]
$ jupyter nbextension enable <package>   # likewise

We're trying to figure out how to deal with this in Debian. Ideally users shouldn't need to run these steps, above.

The "install" step is basically redundant for Debian, it just involves copying files to /usr/share/jupyter/nbextension. So instead of installing the <package> files as a python module (whose sole purpose is to wrap non-python files), then calling "install" at runtime to put them into /usr/share/jupyter/nbextension, I'm installing these directly to the latter location, and omitting <package> from the filesystem.

<package> in my specific case is widgetsnbextension. It contains some metadata to describe where it should be installed to, see [1], but otherwise the "contents" is simply /usr/share/jupyter/nbextension/jupyter-js-widgets/extension.js

[1] https://anonscm.debian.org/git/python-modules/packages/ipywidgets.git/tree/widgetsnbextension/widgetsnbextension/__init__.py

So far, so good. But now I'm having trouble trying to automate away the "enable" step. What "enable" does is add an entry to /etc/jupyter/nbconfig/notebook.json. There are two ways of automating this, and I'm not sure which way is the best. They each have their downsides.

postinst hook in all notebook extension packages
================================================

One downside is that I would have to add a hard Depends: python3-notebook | python-notebook to jupyter-nbextension-jupyter-js-widgets, and then run either 

  $ python -m notebook.nbextensions enable jupyter-js-widgets/extension # or
  $ python3 -m notebook.nbextensions enable jupyter-js-widgets/extension

depending on what is available. Note that they do the same thing, i.e. edit the file mentioned above, so it doesn't matter which one is run.

Another downside is that every jupyter-notebook extension would need to have this complexity.

postinst triggers hook in python-notebook, python3-notebook
===========================================================

See https://wiki.debian.org/DpkgTriggers on what triggers are, and I'm sure you've noticed the "processing triggers" messages for man-db, etc.

The up-side of this approach is that extension packages don't need an extra Depends, and they don't need to do any extra work in their own packages.

However, it's unclear how to write the trigger. The "naive" thing is to do this:

python{,3}-notebook.postinst:
[..]
case "$1" in
    [..]
    triggered)
        cd /usr/share/jupyter/nbextensions
        find -name '*.js' -exec sh -c \
            'f="${1%.js}"; f="${f#./}"; \
             python{,3} -m notebook.nbextensions enable --sys-prefix "$f"' \
            -- '{}' \;
    ;;
    [..]
esac
[..]

However there are two down-sides to this:

1. We might pick up extraneous *.js files that extension packages might install. There's nothing to prevent this, from upstream's point of view - users need to specify a particular extension, but the installed files could contain other non-extension js files. The attempts to install these files might fail, which would obfuscate real errors.

2. There is an extra arg to the "enable" subcommand:

  --section=<Unicode> (ToggleNBExtensionApp.section)
      Default: 'notebook'
      Which config section to add the extension to, 'common' will affect all
      pages.

If this is set to a value other than "notebook", then the file being edited would be /etc/jupyter/nbconfig/${that-value}.json instead of notebook.json.

Or, if we were enabling a python module (that wraps the plain extension e.g. the <package> that we got rid of earlier), the section is automatically taken from the "section" key within that python module (e.g. see [1] above again) - instead of implicitly being "notebook".

In practise, I haven't seen anyone use anything other than the "notebook" value, and I don't know how important or common the other cases are. However, it does mean that the above "naive postinst trigger" is not technically correct, and is missing information.

So, I'm not sure of the best way to proceed here; some advice would be much appreciated.

X

-- 
GPG: ed25519/56034877E1F87C35
GPG: rsa4096/1318EFAC5FBBDBCE
https://github.com/infinity0/pubkeys.git



More information about the Debian-science-sagemath mailing list