##// END OF EJS Templates
add info-level log indicating that notebook is being executed
MinRK -
Show More
@@ -1,142 +1,143 b''
1 """Module containing a preprocessor that removes the outputs from code cells"""
1 """Module containing a preprocessor that removes the outputs from code cells"""
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import os
6 import os
7 import sys
7 import sys
8
8
9 try:
9 try:
10 from queue import Empty # Py 3
10 from queue import Empty # Py 3
11 except ImportError:
11 except ImportError:
12 from Queue import Empty # Py 2
12 from Queue import Empty # Py 2
13
13
14 from IPython.utils.traitlets import List, Unicode
14 from IPython.utils.traitlets import List, Unicode
15
15
16 from IPython.nbformat.current import reads, NotebookNode, writes
16 from IPython.nbformat.current import reads, NotebookNode, writes
17 from .base import Preprocessor
17 from .base import Preprocessor
18 from IPython.utils.traitlets import Integer
18 from IPython.utils.traitlets import Integer
19
19
20 class ExecutePreprocessor(Preprocessor):
20 class ExecutePreprocessor(Preprocessor):
21 """
21 """
22 Executes all the cells in a notebook
22 Executes all the cells in a notebook
23 """
23 """
24
24
25 timeout = Integer(30, config=True,
25 timeout = Integer(30, config=True,
26 help="The time to wait (in seconds) for output from executions."
26 help="The time to wait (in seconds) for output from executions."
27 )
27 )
28 # FIXME: to be removed with nbformat v4
28 # FIXME: to be removed with nbformat v4
29 # map msg_type to v3 output_type
29 # map msg_type to v3 output_type
30 msg_type_map = {
30 msg_type_map = {
31 "error" : "pyerr",
31 "error" : "pyerr",
32 "execute_result" : "pyout",
32 "execute_result" : "pyout",
33 }
33 }
34
34
35 # FIXME: to be removed with nbformat v4
35 # FIXME: to be removed with nbformat v4
36 # map mime-type to v3 mime-type keys
36 # map mime-type to v3 mime-type keys
37 mime_map = {
37 mime_map = {
38 "text/plain" : "text",
38 "text/plain" : "text",
39 "text/html" : "html",
39 "text/html" : "html",
40 "image/svg+xml" : "svg",
40 "image/svg+xml" : "svg",
41 "image/png" : "png",
41 "image/png" : "png",
42 "image/jpeg" : "jpeg",
42 "image/jpeg" : "jpeg",
43 "text/latex" : "latex",
43 "text/latex" : "latex",
44 "application/json" : "json",
44 "application/json" : "json",
45 "application/javascript" : "javascript",
45 "application/javascript" : "javascript",
46 }
46 }
47
47
48 extra_arguments = List(Unicode)
48 extra_arguments = List(Unicode)
49
49
50 def preprocess(self, nb, resources):
50 def preprocess(self, nb, resources):
51 from IPython.kernel import run_kernel
51 from IPython.kernel import run_kernel
52 kernel_name = nb.metadata.get('kernelspec', {}).get('name', 'python')
52 kernel_name = nb.metadata.get('kernelspec', {}).get('name', 'python')
53 self.log.info("Executing notebook with kernel: %s" % kernel_name)
53 with run_kernel(kernel_name=kernel_name,
54 with run_kernel(kernel_name=kernel_name,
54 extra_arguments=self.extra_arguments,
55 extra_arguments=self.extra_arguments,
55 stderr=open(os.devnull, 'w')) as kc:
56 stderr=open(os.devnull, 'w')) as kc:
56 self.kc = kc
57 self.kc = kc
57 nb, resources = super(ExecutePreprocessor, self).preprocess(nb, resources)
58 nb, resources = super(ExecutePreprocessor, self).preprocess(nb, resources)
58 return nb, resources
59 return nb, resources
59
60
60 def preprocess_cell(self, cell, resources, cell_index):
61 def preprocess_cell(self, cell, resources, cell_index):
61 """
62 """
62 Apply a transformation on each code cell. See base.py for details.
63 Apply a transformation on each code cell. See base.py for details.
63 """
64 """
64 if cell.cell_type != 'code':
65 if cell.cell_type != 'code':
65 return cell, resources
66 return cell, resources
66 try:
67 try:
67 outputs = self.run_cell(self.kc.shell_channel, self.kc.iopub_channel, cell)
68 outputs = self.run_cell(self.kc.shell_channel, self.kc.iopub_channel, cell)
68 except Exception as e:
69 except Exception as e:
69 self.log.error("failed to run cell: " + repr(e))
70 self.log.error("failed to run cell: " + repr(e))
70 self.log.error(str(cell.input))
71 self.log.error(str(cell.input))
71 raise
72 raise
72 cell.outputs = outputs
73 cell.outputs = outputs
73 return cell, resources
74 return cell, resources
74
75
75 def run_cell(self, shell, iopub, cell):
76 def run_cell(self, shell, iopub, cell):
76 msg_id = shell.execute(cell.input)
77 msg_id = shell.execute(cell.input)
77 self.log.debug("Executing cell:\n%s", cell.input)
78 self.log.debug("Executing cell:\n%s", cell.input)
78 # wait for finish, with timeout
79 # wait for finish, with timeout
79 while True:
80 while True:
80 try:
81 try:
81 msg = shell.get_msg(timeout=self.timeout)
82 msg = shell.get_msg(timeout=self.timeout)
82 except Empty:
83 except Empty:
83 self.log.error("Timeout waiting for execute reply")
84 self.log.error("Timeout waiting for execute reply")
84 raise
85 raise
85 if msg['parent_header'].get('msg_id') == msg_id:
86 if msg['parent_header'].get('msg_id') == msg_id:
86 break
87 break
87 else:
88 else:
88 # not our reply
89 # not our reply
89 continue
90 continue
90
91
91 outs = []
92 outs = []
92
93
93 while True:
94 while True:
94 try:
95 try:
95 msg = iopub.get_msg(timeout=self.timeout)
96 msg = iopub.get_msg(timeout=self.timeout)
96 except Empty:
97 except Empty:
97 self.log.warn("Timeout waiting for IOPub output")
98 self.log.warn("Timeout waiting for IOPub output")
98 break
99 break
99 if msg['parent_header'].get('msg_id') != msg_id:
100 if msg['parent_header'].get('msg_id') != msg_id:
100 # not an output from our execution
101 # not an output from our execution
101 continue
102 continue
102
103
103 msg_type = msg['msg_type']
104 msg_type = msg['msg_type']
104 self.log.debug("output: %s", msg_type)
105 self.log.debug("output: %s", msg_type)
105 content = msg['content']
106 content = msg['content']
106 out = NotebookNode(output_type=self.msg_type_map.get(msg_type, msg_type))
107 out = NotebookNode(output_type=self.msg_type_map.get(msg_type, msg_type))
107
108
108 # set the prompt number for the input and the output
109 # set the prompt number for the input and the output
109 if 'execution_count' in content:
110 if 'execution_count' in content:
110 cell['prompt_number'] = content['execution_count']
111 cell['prompt_number'] = content['execution_count']
111 out.prompt_number = content['execution_count']
112 out.prompt_number = content['execution_count']
112
113
113 if msg_type == 'status':
114 if msg_type == 'status':
114 if content['execution_state'] == 'idle':
115 if content['execution_state'] == 'idle':
115 break
116 break
116 else:
117 else:
117 continue
118 continue
118 elif msg_type in {'execute_input', 'pyin'}:
119 elif msg_type in {'execute_input', 'pyin'}:
119 continue
120 continue
120 elif msg_type == 'clear_output':
121 elif msg_type == 'clear_output':
121 outs = []
122 outs = []
122 continue
123 continue
123
124
124 if msg_type == 'stream':
125 if msg_type == 'stream':
125 out.stream = content['name']
126 out.stream = content['name']
126 out.text = content['text']
127 out.text = content['text']
127 elif msg_type in ('display_data', 'execute_result'):
128 elif msg_type in ('display_data', 'execute_result'):
128 out['metadata'] = content['metadata']
129 out['metadata'] = content['metadata']
129 for mime, data in content['data'].items():
130 for mime, data in content['data'].items():
130 # map mime-type keys to nbformat v3 keys
131 # map mime-type keys to nbformat v3 keys
131 # this will be unnecessary in nbformat v4
132 # this will be unnecessary in nbformat v4
132 key = self.mime_map.get(mime, mime)
133 key = self.mime_map.get(mime, mime)
133 out[key] = data
134 out[key] = data
134 elif msg_type == 'error':
135 elif msg_type == 'error':
135 out.ename = content['ename']
136 out.ename = content['ename']
136 out.evalue = content['evalue']
137 out.evalue = content['evalue']
137 out.traceback = content['traceback']
138 out.traceback = content['traceback']
138 else:
139 else:
139 self.log.error("unhandled iopub msg: " + msg_type)
140 self.log.error("unhandled iopub msg: " + msg_type)
140
141
141 outs.append(out)
142 outs.append(out)
142 return outs
143 return outs
General Comments 0
You need to be logged in to leave comments. Login now