##// END OF EJS Templates
Add preprocessor to execute notebooks
Julia Evans -
Show More
@@ -0,0 +1,109 b''
1 """Module containing a preprocessor that removes the outputs from code cells"""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 #-----------------------------------------------------------------------------
7 # Imports
8 #-----------------------------------------------------------------------------
9
10 import os
11 import sys
12
13 from Queue import Empty
14 from IPython.kernel import KernelManager
15 from IPython.nbformat.current import reads, NotebookNode, writes
16
17 from .base import Preprocessor
18
19
20 #-----------------------------------------------------------------------------
21 # Classes
22 #-----------------------------------------------------------------------------
23 class ExecutePreprocessor(Preprocessor):
24 """
25 Executes all the cells in a notebook
26 """
27 def __init__(self, *args, **kwargs):
28 """
29 Start an kernel to run the Python code
30 """
31 super(ExecutePreprocessor, self).__init__(*args, **kwargs)
32 self.km = KernelManager()
33 # run %pylab inline, because some notebooks assume this
34 # even though they shouldn't
35 self.km.start_kernel(extra_arguments=['--pylab=inline'], stderr=open(os.devnull, 'w'))
36 self.kc = self.km.client()
37 self.kc.start_channels()
38 self.iopub = self.kc.iopub_channel
39 self.shell = self.kc.shell_channel
40
41 self.shell.execute("pass")
42 self.shell.get_msg()
43
44 def preprocess_cell(self, cell, resources, cell_index):
45 """
46 Apply a transformation on each code cell. See base.py for details.
47 """
48 if cell.cell_type != 'code':
49 return cell, resources
50 try:
51 outputs = self.run_cell(self.shell, self.iopub, cell)
52 except Exception as e:
53 print >> sys.stderr, "failed to run cell:", repr(e)
54 print >> sys.stderr, cell.input
55 sys.exit(1)
56 cell.outputs = outputs
57 return cell, resources
58
59 @staticmethod
60 def run_cell(shell, iopub, cell):
61 # print cell.input
62 shell.execute(cell.input)
63 # wait for finish, maximum 20s
64 shell.get_msg(timeout=20)
65 outs = []
66
67 while True:
68 try:
69 msg = iopub.get_msg(timeout=0.2)
70 except Empty:
71 break
72 msg_type = msg['msg_type']
73 if msg_type in ('status', 'pyin'):
74 continue
75 elif msg_type == 'clear_output':
76 outs = []
77 continue
78
79 content = msg['content']
80 # print msg_type, content
81 out = NotebookNode(output_type=msg_type)
82
83 if msg_type == 'stream':
84 out.stream = content['name']
85 out.text = content['data']
86 elif msg_type in ('display_data', 'pyout'):
87 out['metadata'] = content['metadata']
88 for mime, data in content['data'].iteritems():
89 attr = mime.split('/')[-1].lower()
90 # this gets most right, but fix svg+html, plain
91 attr = attr.replace('+xml', '').replace('plain', 'text')
92 setattr(out, attr, data)
93 if msg_type == 'pyout':
94 out.prompt_number = content['execution_count']
95 elif msg_type == 'pyerr':
96 out.ename = content['ename']
97 out.evalue = content['evalue']
98 out.traceback = content['traceback']
99 else:
100 print >> sys.stderr, "unhandled iopub msg:", msg_type
101
102 outs.append(out)
103 return outs
104
105
106 def __del__(self):
107 self.kc.stop_channels()
108 self.km.shutdown_kernel()
109 del self.km
@@ -0,0 +1,45 b''
1 """
2 Module with tests for the clearoutput preprocessor.
3 """
4
5 # Copyright (c) IPython Development Team.
6 # Distributed under the terms of the Modified BSD License.
7
8 #-----------------------------------------------------------------------------
9 # Imports
10 #-----------------------------------------------------------------------------
11 import copy
12
13 from IPython.nbformat import current as nbformat
14
15 from .base import PreprocessorTestsBase
16 from ..execute import ExecutePreprocessor
17
18
19 #-----------------------------------------------------------------------------
20 # Class
21 #-----------------------------------------------------------------------------
22
23 class TestExecute(PreprocessorTestsBase):
24 """Contains test functions for execute.py"""
25
26
27 def build_preprocessor(self):
28 """Make an instance of a preprocessor"""
29 preprocessor = ExecutePreprocessor()
30 preprocessor.enabled = True
31 return preprocessor
32
33 def test_constructor(self):
34 """Can a ExecutePreprocessor be constructed?"""
35 self.build_preprocessor()
36
37 def test_correct_output(self):
38 """Test that ExecutePreprocessor evaluates a cell to the right thing"""
39 nb = self.build_notebook()
40 res = self.build_resources()
41 nb.worksheets[0].cells[0].input = "print 'hi!'"
42 preprocessor = self.build_preprocessor()
43 nb, res = preprocessor(nb, res)
44 expected_outputs = [{'output_type': 'stream', 'stream': 'stdout', 'text': 'hi!\n'}]
45 assert nb.worksheets[0].cells[0].outputs == expected_outputs
@@ -71,6 +71,7 b' class Exporter(LoggingConfigurable):'
71 'IPython.nbconvert.preprocessors.RevealHelpPreprocessor',
71 'IPython.nbconvert.preprocessors.RevealHelpPreprocessor',
72 'IPython.nbconvert.preprocessors.LatexPreprocessor',
72 'IPython.nbconvert.preprocessors.LatexPreprocessor',
73 'IPython.nbconvert.preprocessors.ClearOutputPreprocessor',
73 'IPython.nbconvert.preprocessors.ClearOutputPreprocessor',
74 'IPython.nbconvert.preprocessors.ExecutePreprocessor',
74 'IPython.nbconvert.preprocessors.HighlightMagicsPreprocessor'],
75 'IPython.nbconvert.preprocessors.HighlightMagicsPreprocessor'],
75 config=True,
76 config=True,
76 help="""List of preprocessors available by default, by name, namespace,
77 help="""List of preprocessors available by default, by name, namespace,
@@ -8,6 +8,7 b' from .latex import LatexPreprocessor'
8 from .csshtmlheader import CSSHTMLHeaderPreprocessor
8 from .csshtmlheader import CSSHTMLHeaderPreprocessor
9 from .highlightmagics import HighlightMagicsPreprocessor
9 from .highlightmagics import HighlightMagicsPreprocessor
10 from .clearoutput import ClearOutputPreprocessor
10 from .clearoutput import ClearOutputPreprocessor
11 from .execute import ExecutePreprocessor
11
12
12 # decorated function Preprocessors
13 # decorated function Preprocessors
13 from .coalescestreams import coalesce_streams
14 from .coalescestreams import coalesce_streams
General Comments 0
You need to be logged in to leave comments. Login now