diff --git a/nbconvert/preprocessors/execute.py b/nbconvert/preprocessors/execute.py index 77eea43c7..94d71cc81 100644 --- a/nbconvert/preprocessors/execute.py +++ b/nbconvert/preprocessors/execute.py @@ -391,3 +391,25 @@ def run_cell(self, cell, cell_index=0): outs.append(out) return outs + + +def executenb(nb, cwd=None, **kwargs): + """Execute a notebook's code, updating outputs within the notebook object. + + This is a convenient wrapper around ExecutePreprocessor. It returns the + modified notebook object. + + Parameters + ---------- + nb : NotebookNode + The notebook object to be executed + cwd : str, optional + If supplied, the kernel will run in this directory + kwargs : + Any other options for ExecutePreprocessor, e.g. timeout, kernel_name + """ + resources = {} + if cwd is not None: + resources['metadata'] = {'path': cwd} + ep = ExecutePreprocessor(**kwargs) + return ep.preprocess(nb, resources)[0] diff --git a/nbconvert/preprocessors/tests/test_execute.py b/nbconvert/preprocessors/tests/test_execute.py index 8f0779f42..244ab38b9 100644 --- a/nbconvert/preprocessors/tests/test_execute.py +++ b/nbconvert/preprocessors/tests/test_execute.py @@ -17,7 +17,7 @@ import sys from .base import PreprocessorTestsBase -from ..execute import ExecutePreprocessor, CellExecutionError +from ..execute import ExecutePreprocessor, CellExecutionError, executenb from nbconvert.filters import strip_ansi from nose.tools import assert_raises, assert_in @@ -222,3 +222,14 @@ def test_custom_kernel_manager(self): for method, call_count in expected: self.assertNotEqual(call_count, 0, '{} was called'.format(method)) + def test_execute_function(self): + # Test the executenb() convenience API + current_dir = os.path.dirname(__file__) + filename = os.path.join(current_dir, 'files', 'HelloWorld.ipynb') + + with io.open(filename) as f: + input_nb = nbformat.read(f, 4) + + original = copy.deepcopy(input_nb) + executed = executenb(original, os.path.dirname(filename)) + self.assert_notebooks_equal(original, executed)