Fragment – Jupyter Book Electron App

Noting an experiment by Ines Montani in creating an electron app wrapped version of the spacy course/python course creator template, I wondered how easy it would be to wrap a static Jekyll / Jupyter Book created site, such as one generated from an OU-XML feedstock, as an electron app.

The reason for doing this? With the book bundled as an electron app, you could download the app and run it, standalone, to view the book, with no web server required. (The web server used to serve the book is bundled inside the electron app.)

A quick search around turned up an electron appifier script (thmsbfft/electron-wrap), which did the job nicely:

cd to the folder that contains the files, and run:

bash <(curl -s https://raw.githubusercontent.com/thmsbfft/electron-wrap/master/wrap.sh)

[The electron-wrap app uses electron/electron-packager], which can be used to build apps for Windows and Linux as well, although the electron-wrap builder failed for me when trying to build anything other than for Mac (I think we need additional settings in package.json? Eg see the vizgraph build.). We can also build apps using CircleCi, although I haven’t test this yet. For example: joeireland/electron-circleci, protonmail-desktop/application, jcf94/vizgraph

If all the js required to handle interactives used in the book is available locally, the book should work, in a fully featured way, even when offline.

(I also noted a script for wrapping a website in an electron app — jiahaog/nativefier — which may be interesting… It can build for various platforms, which would be handy, but it only wraps a website, it doesn’t grab the files and serve them locally inside the app…? See also Google Chrome app mode.)

So what next?

A couple of things I want to try, though probably won’t have a chance to do so for the next couple of weeks at least… (I need a break: holiday, with no computer access… yeah!)

First, getting Jupyter Book python interactions working locally. At the moment, Python code execution is handled by ThebeLab launching a MyBinder container and using a Jupyter server created there to provide execution kernels. But ThebeLab can also run against a local kernel, for example using the connection settings:

 
    {
      bootstrap: true,
      kernelOptions: {
        name: "python3",
        serverSettings: {
          "baseUrl": "http://127.0.0.1:8888",
          "token": "test-secret"
        }
      },
    }
  

and starting the Jupyter server with settings something along the lines of:

jupyter notebook --NotebookApp.token=test-secret --NotebookApp.allow_origin='https://thebelab.readthedocs.io'

(The allow_origin setting is used to allow traffic from another IP domain, such as the domain a ThebeLab page is being served from.)

My primary use case for the local server is so that I can reimagine the delivery of notebooks in the TM351 VM as a Jupyter Book, presenting the notebooks in book form rather than vanilla notebook form and allowing code execution from within the book against the Jupyter server running locally in the VM.

But if Jupyter Book can run against a local kernel, then could we also distribute, and run, a Jupyter server / kernel within the electron app? This post on Building a deployable Python-Electron App suggests a possible way, using pyinstaller to “freeze (package) Python applications into stand-alone executables, under Windows, GNU/Linux, Mac OS X, FreeBSD, Solaris and AIX”. Said executables could then be added to the electron app and provide the Python environment within the app, which means it should run in a standalone mode, without the need for the user to have Python, a Jupyter server environment, or the required Python environment installed elsewhere on their machine? Download the electron book app and it should just run; and the code should run against the locally bundled Jupyter kernel; and it should all work offline, too, with no other installation requirements or side-effects. And in a cross-platform way. Perfect for OUr students…

An alternative, perhaps easier, approach might be to bundle a conda environment in the electron app. In this case, snakestagram could help automate the selection of an appropriate environment for different platforms (h/t @betatim for clarifying what snakestagram does).

(I’m not sure we could go the whole way and put all the TM351 environment into an electron app — we call on Postgres, MongodDB and OpenRefine too — but in the course materials a lot of the Postgres query activities could be replaced with a SQLite3 backend.)

Looking around, a lot of electron apps seem to require the additional installation of Python environments on host that are then called from the electron app (example). Finding a robust recipe for bundling Python environments within electron apps would be really useful I think?

There are a couple of Jupyter electron apps out there already, aside from nteract, (which runs against an external kernel). For example, jupyterlab/jupyterlab_app, which also runs against an external kernel, and AgrawalAmey/nnfl-app, which looks like it downloads Anaconda on first run (I’m not sure if the installation is “outside” the app, onto host filesystem? Or does it add it to a filesystem within the electron app context?). The nnfl-app also has support for assignment handling and assignment uploads to a complementary server (about: Jupyter In Classroom).

Finally, I wonder if Jupyter Book could run Python code within the browser environment that the electron app essentially provides using Pyodide, “the Python scientific stack, compiled to WebAssembly” that gives Python access within the browser?

Author: Tony Hirst

I'm a Senior Lecturer at The Open University, with an interest in #opendata policy and practice, as well as general web tinkering...