-
Notifications
You must be signed in to change notification settings - Fork 0
/
nbrunner.py
47 lines (39 loc) · 1.44 KB
/
nbrunner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import glob2
import itertools
import os
import pathlib
import nbformat
from flask import Flask, abort, render_template, request
from nbconvert.exporters import HTMLExporter
from nbconvert.preprocessors import ExecutePreprocessor
app = Flask(__name__)
@app.route('/render')
def render():
root = pathlib.Path(os.environ['NBRUNNER_ROOT'])
path = request.args.get('file', '')
if not path.endswith('.ipynb'):
abort(404)
try:
filepath = pathlib.Path(root, path)
fp = filepath.open('r')
notebook = nbformat.read(fp, as_version=4)
except FileNotFoundError:
abort(404)
pre = ExecutePreprocessor()
pre.preprocess(notebook, {'metadata': {'path': str(filepath.parent)}})
exporter = HTMLExporter()
body, resources = exporter.from_notebook_node(notebook)
return body
@app.route('/')
def index():
# unfortunately, pathlib.{i,}glob cannot be used in most versions < 3.6
# due to a bug with permissions - see http://bugs.python.org/issue24120
root = os.path.normpath(os.environ['NBRUNNER_ROOT'])
files = glob2.glob('{}/**/*.ipynb'.format(root))
file_items = itertools.groupby(sorted(files), lambda f: os.path.dirname(f))
folder_files = {}
for path, items in file_items:
folder_files[path] = [(os.path.relpath(file, root), os.path.basename(file)) for file in items]
return render_template('index.html', files=folder_files)
if __name__ == '__main__':
app.run()