Jonathan Wheeler
Jonathan Wheeler

Reputation: 2699

Render jupyter ipynb int html in Flask

I'm a graduate student researcher, and I want to make a read-only index of all of my ipynb files that I and my colleagues can quickly search.

I can convert ipynb to html using this command

jupyter nbconvert --format=basic my_notebook.ipynb

Then I get an html file that I can render with a flask server (with extra templates, css, table of contents, index, etc...). However, I don't want to manually convert all of the ipynb files into html files everytime I make/upgrade them. I'd rather have the Flask server search through a directory, find all of the ipynb files, and then show me a directory tree, and when I click on a notebook in my directory tree, do the ipynb -> notebook conversion and render the html.

My question is: how do I convert a jupyter notebook file held in notebook_filename into html, and store that html in notebook_html_contents in Flask during runtime? Is there a better way than to do a Popen.subprocess?

I understand the benefits of caching, but I'm going to be writing files probably twice as often as I read them. Having a bunch of html files will also clutter up my file structure and double the amount of memory I use.

Upvotes: 2

Views: 4867

Answers (2)

Jonathan Wheeler
Jonathan Wheeler

Reputation: 2699

This is a little hacky, but you can do it with this script:

import io, sys
from nbconvert.nbconvertapp import main

file = 'somefile.ipynb'
argv = ['--template=basic', '--stdout', file]
print (argv[1:])

capture = io.StringIO()
sys.stdout = capture # redirect stdout

main(argv)

sys.stdout = sys.__stdout__ # send stdout to normal place again
output = capture.getvalue()

Explanation

There's a lot of code rolling around between jupyter-nbconvert, JupyterApp, traitlets.config.application, etc... Rather than mess with all of that stuff (and have it break whenever there's an upgrade, we can run code similar to what nbconvert does on init (simply runs main with some massaged argv).

Upvotes: 0

m01
m01

Reputation: 9395

nbviewer

nbviewer lets you do exactly what I think you want: render your notebooks on demand, and give you an interface to navigate to them.

While by default used to render notebooks from online sources, it does have an option to let you traverse and render local notebooks: Simply run it with the --localfiles=/path/to/your/notebooks option, and navigate to http://localhost:8080/localfile to get a directory browser which lets you click on .ipynb files to view them.

(replace localhost if appropriate with the IP of the machine you're running nbviewer on)

Quick example (using Docker):

docker pull jupyter/nbviewer
docker run -p 8080:8080 jupyter/nbviewer python3 -m nbviewer --port=8080 --localfiles=/tmp

In another terminal:

docker cp ~/path/to/some/notebook.ipynb <name of container>:/tmp

Now, navigate to http://localhost:8080/localfile.

Customisation

You may of course wish to look into using a local installation rather than using Docker, depending on your circumstances. It's also worth running the nbviewer with --help and tweak the command line options to suit your needs.

Bonus: customising the front page

Note: The actual front page of nbviewer (http://localhost:8080) comes from a JSON file. You may find a JSON file similar to the following more to your liking:

{"title": "nbviewer",
 "subtitle": "My Notebooks",
 "text": "Click on the link below",
 "show_input": false,
 "sections":[
   {
     "header":"My local notebooks",
     "links":[
       {
         "text": "Starting directory",
         "target": "localfile",
         "img": "/static/img/example-nb/fitting.png"
       }
     ]
   }
 ]
}

Upvotes: 4

Related Questions