public
Created

Run and save a ipynb file from the command line. This script is working in dev version (1.0) of IPython (for previous version you have to tweak it). It will generate a new "run & saved" notebook.

  • Download Gist
ipynb_run_save.py
Python
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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
#!/usr/bin/env python
"""
Script for running and save notebooks from command line.
 
How to use: `ipynb_run_save.py foo.ipynb
 
Some tweaks over ipydoctest.py from minrk
 
by @damianavila
"""
 
import io
import os
import sys
 
from Queue import Empty
 
from IPython.kernel.blockingkernelmanager import BlockingKernelManager
from IPython.nbformat.current import read, write, NotebookNode
 
 
def run_cell(km, cell):
shell = km.shell_channel
iopub = km.iopub_channel
# print "\n\ntesting:"
# print cell.input
shell.execute(cell.input)
# wait for finish, maximum 20s
shell.get_msg(timeout=20)
outs = []
 
while True:
try:
msg = iopub.get_msg(timeout=0.2)
except Empty:
break
msg_type = msg['msg_type']
if msg_type in ('status', 'pyin'):
continue
elif msg_type == 'clear_output':
outs = []
continue
 
content = msg['content']
# print msg_type, content
out = NotebookNode(output_type=msg_type)
 
if msg_type == 'stream':
out.stream = content['name']
out.text = content['data']
elif msg_type in ('display_data', 'pyout'):
for mime, data in content['data'].iteritems():
attr = mime.split('/')[-1].lower()
# this gets most right, but fix svg+html, plain
attr = attr.replace('+xml', '').replace('plain', 'text')
setattr(out, attr, data)
if msg_type == 'pyout':
out.prompt_number = content['execution_count']
elif msg_type == 'pyerr':
out.ename = content['ename']
out.evalue = content['evalue']
out.traceback = content['traceback']
else:
print "unhandled iopub msg:", msg_type
 
outs.append(out)
return outs
 
 
def test_notebook(nb):
km = BlockingKernelManager()
km.start_kernel(extra_arguments=['--pylab=inline'], stderr=open(os.devnull, 'w'))
km.start_channels()
# run %pylab inline, because some notebooks assume this
# even though they shouldn't
km.shell_channel.execute("pass")
km.shell_channel.get_msg()
while True:
try:
km.iopub_channel.get_msg(timeout=1)
except Empty:
break
 
errors = 0
cells = 0
for ws in nb.worksheets:
for cell in ws.cells:
if cell.cell_type != 'code':
continue
cells += 1
try:
outs = run_cell(km, cell)
except Exception as e:
print "failed to run cell:", repr(e)
print cell.input
errors += 1
continue
cell.outputs = outs
 
if errors:
print " %3i cells failed to complete" % errors
if cells:
print "%i code cells from notebook %s" % (cells, nb.metadata.name)
km.shutdown_kernel()
del km
 
if __name__ == '__main__':
for ipynb in sys.argv[1:]:
print "running %s" % ipynb
with io.open(ipynb, encoding='utf8') as f:
nb = read(f, 'json')
test_notebook(nb)
base, ext = os.path.splitext(ipynb)
new_ipynb = "%s_run_saved%s" % (base, ext)
with io.open(new_ipynb, 'w', encoding='utf8') as f:
write(nb, f, 'json')
print "wrote %s" % new_ipynb

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.