execute.py
111 lines
| 3.6 KiB
| text/x-python
|
PythonLexer
Julia Evans
|
r17074 | """Module containing a preprocessor that removes the outputs from code cells""" | ||
# Copyright (c) IPython Development Team. | ||||
# Distributed under the terms of the Modified BSD License. | ||||
import os | ||||
import sys | ||||
Julia Evans
|
r17087 | try: | ||
from queue import Empty # Py 3 | ||||
except ImportError: | ||||
from Queue import Empty # Py 2 | ||||
MinRK
|
r17092 | from IPython.utils.traitlets import List, Unicode | ||
Julia Evans
|
r17074 | |||
MinRK
|
r18582 | from IPython.nbformat.current import reads, writes, output_from_msg | ||
Julia Evans
|
r17074 | from .base import Preprocessor | ||
MinRK
|
r17094 | from IPython.utils.traitlets import Integer | ||
Julia Evans
|
r17074 | |||
class ExecutePreprocessor(Preprocessor): | ||||
""" | ||||
Executes all the cells in a notebook | ||||
""" | ||||
MinRK
|
r17092 | |||
MinRK
|
r17094 | timeout = Integer(30, config=True, | ||
help="The time to wait (in seconds) for output from executions." | ||||
) | ||||
MinRK
|
r17092 | |||
extra_arguments = List(Unicode) | ||||
Julia Evans
|
r17079 | |||
Julia Evans
|
r17080 | def preprocess(self, nb, resources): | ||
Thomas Kluyver
|
r17822 | from IPython.kernel import run_kernel | ||
kernel_name = nb.metadata.get('kernelspec', {}).get('name', 'python') | ||||
MinRK
|
r18458 | self.log.info("Executing notebook with kernel: %s" % kernel_name) | ||
Thomas Kluyver
|
r17822 | with run_kernel(kernel_name=kernel_name, | ||
extra_arguments=self.extra_arguments, | ||||
stderr=open(os.devnull, 'w')) as kc: | ||||
self.kc = kc | ||||
nb, resources = super(ExecutePreprocessor, self).preprocess(nb, resources) | ||||
Julia Evans
|
r17079 | return nb, resources | ||
Julia Evans
|
r17074 | def preprocess_cell(self, cell, resources, cell_index): | ||
""" | ||||
Apply a transformation on each code cell. See base.py for details. | ||||
""" | ||||
if cell.cell_type != 'code': | ||||
return cell, resources | ||||
try: | ||||
Thomas Kluyver
|
r17822 | outputs = self.run_cell(self.kc.shell_channel, self.kc.iopub_channel, cell) | ||
Julia Evans
|
r17074 | except Exception as e: | ||
Julia Evans
|
r17078 | self.log.error("failed to run cell: " + repr(e)) | ||
MinRK
|
r18580 | self.log.error(str(cell.source)) | ||
MinRK
|
r17092 | raise | ||
Julia Evans
|
r17074 | cell.outputs = outputs | ||
return cell, resources | ||||
MinRK
|
r17092 | def run_cell(self, shell, iopub, cell): | ||
MinRK
|
r18580 | msg_id = shell.execute(cell.source) | ||
self.log.debug("Executing cell:\n%s", cell.source) | ||||
MinRK
|
r17092 | # wait for finish, with timeout | ||
while True: | ||||
try: | ||||
MinRK
|
r17094 | msg = shell.get_msg(timeout=self.timeout) | ||
MinRK
|
r17092 | except Empty: | ||
self.log.error("Timeout waiting for execute reply") | ||||
raise | ||||
if msg['parent_header'].get('msg_id') == msg_id: | ||||
break | ||||
else: | ||||
# not our reply | ||||
continue | ||||
Julia Evans
|
r17074 | outs = [] | ||
Julia Evans
|
r17077 | |||
Julia Evans
|
r17074 | while True: | ||
try: | ||||
MinRK
|
r17094 | msg = iopub.get_msg(timeout=self.timeout) | ||
Julia Evans
|
r17074 | except Empty: | ||
MinRK
|
r17092 | self.log.warn("Timeout waiting for IOPub output") | ||
Julia Evans
|
r17074 | break | ||
MinRK
|
r17092 | if msg['parent_header'].get('msg_id') != msg_id: | ||
# not an output from our execution | ||||
continue | ||||
Jessica B. Hamrick
|
r17090 | |||
Julia Evans
|
r17074 | msg_type = msg['msg_type'] | ||
MinRK
|
r17092 | self.log.debug("output: %s", msg_type) | ||
Jessica B. Hamrick
|
r17090 | content = msg['content'] | ||
Jessica B. Hamrick
|
r17824 | |||
# set the prompt number for the input and the output | ||||
if 'execution_count' in content: | ||||
MinRK
|
r18587 | cell['execution_count'] = content['execution_count'] | ||
Jessica B. Hamrick
|
r17824 | |||
MinRK
|
r17092 | if msg_type == 'status': | ||
if content['execution_state'] == 'idle': | ||||
break | ||||
else: | ||||
continue | ||||
MinRK
|
r18582 | elif msg_type == 'execute_input': | ||
MinRK
|
r17092 | continue | ||
elif msg_type == 'clear_output': | ||||
outs = [] | ||||
continue | ||||
MinRK
|
r18580 | |||
MinRK
|
r18582 | try: | ||
out = output_from_msg(msg) | ||||
except ValueError: | ||||
Julia Evans
|
r17078 | self.log.error("unhandled iopub msg: " + msg_type) | ||
MinRK
|
r18582 | else: | ||
outs.append(out) | ||||
Julia Evans
|
r17077 | |||
Julia Evans
|
r17074 | return outs | ||