Skip to content

Commit

Permalink
preproc
Browse files Browse the repository at this point in the history
  • Loading branch information
jph00 committed Jun 7, 2022
1 parent 0eef6a4 commit d6e7c64
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 40 deletions.
21 changes: 12 additions & 9 deletions execnb/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ def publish(self, data, metadata=None, **kwargs): self.shell._add_out(data, meta
def _out_exc(ename, evalue, traceback): return dict(ename=str(ename), evalue=str(evalue), output_type='error', traceback=traceback)
def _out_stream(text): return dict(name='stdout', output_type='stream', text=text.splitlines(False))

# %% ../nbs/02_shell.ipynb 6
# %% ../nbs/02_shell.ipynb 7
class CaptureShell(FastInteractiveShell):
"Execute the IPython/Jupyter source code"
def __init__(self):
super().__init__(displayhook_class=_CaptureHook, display_pub_class=_CapturePub)
InteractiveShell._instance = self
Expand Down Expand Up @@ -62,7 +63,7 @@ def _stream(self, std):
text = std.getvalue()
if text: self.out.append(_out_stream(text))

# %% ../nbs/02_shell.ipynb 9
# %% ../nbs/02_shell.ipynb 10
@patch
def run(self:CaptureShell, code:str, stdout=True, stderr=True):
"runs `code`, returning a list of all outputs in Jupyter notebook format"
Expand All @@ -76,7 +77,7 @@ def run(self:CaptureShell, code:str, stdout=True, stderr=True):
self._stream(stdout)
return [*self.out]

# %% ../nbs/02_shell.ipynb 18
# %% ../nbs/02_shell.ipynb 19
@patch
def cell(self:CaptureShell, cell, stdout=True, stderr=True):
"Run `cell`, skipping if not code, and store outputs back in cell"
Expand All @@ -87,18 +88,20 @@ def cell(self:CaptureShell, cell, stdout=True, stderr=True):
for o in outs:
if 'execution_count' in o: cell['execution_count'] = o['execution_count']

# %% ../nbs/02_shell.ipynb 21
# %% ../nbs/02_shell.ipynb 23
@patch
def run_all(self:CaptureShell, nb, exc_stop=False):
def run_all(self:CaptureShell, nb, exc_stop=False, preproc=noop, postproc=noop):
"Run all cells in `nb`, stopping at first exception if `exc_stop`"
for cell in nb.cells:
self.cell(cell)
if not preproc(cell):
self.cell(cell)
postproc(cell)
if self.exc and exc_stop: raise self.exc[1] from None

# %% ../nbs/02_shell.ipynb 29
# %% ../nbs/02_shell.ipynb 36
@patch
def execute(self:CaptureShell, src, dest, exc_stop=False):
def execute(self:CaptureShell, src, dest, exc_stop=False, preproc=noop, postproc=noop):
"Execute notebook from `src` and save with outputs to `dest"
nb = read_nb(src)
self.run_all(nb, exc_stop=exc_stop)
self.run_all(nb, exc_stop=exc_stop, preproc=preproc, postproc=postproc)
write_nb(nb, dest)
1 change: 1 addition & 0 deletions nbs/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
docs/
/.quarto/
138 changes: 107 additions & 31 deletions nbs/02_shell.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@
"def _out_stream(text): return dict(name='stdout', output_type='stream', text=text.splitlines(False))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## CaptureShell -"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -78,6 +85,7 @@
"source": [
"#|export\n",
"class CaptureShell(FastInteractiveShell):\n",
" \"Execute the IPython/Jupyter source code\"\n",
" def __init__(self):\n",
" super().__init__(displayhook_class=_CaptureHook, display_pub_class=_CapturePub)\n",
" InteractiveShell._instance = self\n",
Expand Down Expand Up @@ -107,19 +115,19 @@
]
},
{
"cell_type": "markdown",
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Use `CaptureShell` to execute the IPython/Jupyter source code."
"s = CaptureShell()"
]
},
{
"cell_type": "code",
"execution_count": null,
"cell_type": "markdown",
"metadata": {},
"outputs": [],
"source": [
"s = CaptureShell()"
"### Cells -"
]
},
{
Expand Down Expand Up @@ -184,8 +192,8 @@
" 'execution_count': 1},\n",
" {'name': 'stdout',\n",
" 'output_type': 'stream',\n",
" 'text': ['CPU times: user 2 us, sys: 0 ns, total: 2 us',\n",
" 'Wall time: 3.58 us']}]"
" 'text': ['CPU times: user 1 us, sys: 0 ns, total: 1 us',\n",
" 'Wall time: 3.34 us']}]"
]
},
"execution_count": null,
Expand Down Expand Up @@ -358,6 +366,13 @@
"c.outputs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### NBs -"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -366,10 +381,12 @@
"source": [
"#|export\n",
"@patch\n",
"def run_all(self:CaptureShell, nb, exc_stop=False):\n",
"def run_all(self:CaptureShell, nb, exc_stop=False, preproc=noop, postproc=noop):\n",
" \"Run all cells in `nb`, stopping at first exception if `exc_stop`\"\n",
" for cell in nb.cells:\n",
" self.cell(cell)\n",
" if not preproc(cell):\n",
" self.cell(cell)\n",
" postproc(cell)\n",
" if self.exc and exc_stop: raise self.exc[1] from None"
]
},
Expand Down Expand Up @@ -401,11 +418,7 @@
{
"data": {
"text/plain": [
"[{'data': {'text/plain': ['<IPython.core.display.Markdown object>'],\n",
" 'text/markdown': [\"This is *bold*. Here's a [link](https://www.fast.ai).\"]},\n",
" 'metadata': {},\n",
" 'output_type': 'execute_result',\n",
" 'execution_count': 5}]"
"(#0) []"
]
},
"execution_count": null,
Expand Down Expand Up @@ -453,13 +466,7 @@
{
"data": {
"text/plain": [
"[{'ename': \"<class 'Exception'>\",\n",
" 'evalue': 'Oopsie!',\n",
" 'output_type': 'error',\n",
" 'traceback': ['\\x1b[0;31m---------------------------------------------------------------------------\\x1b[0m',\n",
" '\\x1b[0;31mException\\x1b[0m Traceback (most recent call last)',\n",
" 'Input \\x1b[0;32mIn [1]\\x1b[0m, in \\x1b[0;36m<cell line: 1>\\x1b[0;34m()\\x1b[0m\\n\\x1b[0;32m----> 1\\x1b[0m \\x1b[38;5;28;01mraise\\x1b[39;00m \\x1b[38;5;167;01mException\\x1b[39;00m(\\x1b[38;5;124m\"\\x1b[39m\\x1b[38;5;124mOopsie!\\x1b[39m\\x1b[38;5;124m\"\\x1b[39m)\\n',\n",
" '\\x1b[0;31mException\\x1b[0m: Oopsie!']}]"
"(#0) []"
]
},
"execution_count": null,
Expand All @@ -478,22 +485,65 @@
"With `exc_stop=True` (the default), exceptions in a cell are raised and no further processing occurs:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"try: s.run_all(nb, exc_stop=True)\n",
"except Exception as e: print(f\"got exception: {e}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can pass a function to `preproc` to have it run on every cell. It can modify the cell as needed. If the function returns `True`, then that cell will not be executed. For instance, to skip the cell which raises an exception:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"nb = read_nb(clean)\n",
"s.run_all(nb, preproc=lambda c: 'raise' in c.source)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This cell will contain no output, since it was skipped."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"got exception: Oopsie!\n"
]
"data": {
"text/plain": [
"(#0) []"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"try: s.run_all(nb, exc_stop=True)\n",
"except Exception as e: print(f\"got exception: {e}\")"
"nb.cells[-1].outputs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also pass a function to `postproc` to modify a cell after it is executed."
]
},
{
Expand All @@ -504,13 +554,20 @@
"source": [
"#|export\n",
"@patch\n",
"def execute(self:CaptureShell, src, dest, exc_stop=False):\n",
"def execute(self:CaptureShell, src, dest, exc_stop=False, preproc=noop, postproc=noop):\n",
" \"Execute notebook from `src` and save with outputs to `dest\"\n",
" nb = read_nb(src)\n",
" self.run_all(nb, exc_stop=exc_stop)\n",
" self.run_all(nb, exc_stop=exc_stop, preproc=preproc, postproc=postproc)\n",
" write_nb(nb, dest)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is a shortcut for the combination of `read_nb`, `run_all`, and `write_nb`."
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -531,6 +588,25 @@
"finally: Path('tmp.ipynb').unlink()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## export -"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#|hide\n",
"#|eval: false\n",
"from nbprocess.doclinks import nbprocess_export\n",
"nbprocess_export()"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
18 changes: 18 additions & 0 deletions nbs/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.cell-output pre {
margin-left: 0.8rem;
margin-top: 0;
background: none;
border-left: 2px solid lightsalmon;
border-top-left-radius: 0;
border-top-right-radius: 0;
}

.cell-output .sourceCode {
background: none;
margin-top: 0;
}

.cell > .sourceCode {
margin-bottom: 0;
}

0 comments on commit d6e7c64

Please sign in to comment.