Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
choldgraf committed Mar 12, 2020
1 parent efe3b1a commit f1d5c15
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 152 deletions.
2 changes: 1 addition & 1 deletion nbclean/__init__.py
Expand Up @@ -3,4 +3,4 @@
__version__ = "0.3.2"

from .clean import NotebookCleaner
from .run import run_notebook_directory, run_notebook
from .run import run_notebooks, run_notebook
12 changes: 11 additions & 1 deletion nbclean/clean.py
Expand Up @@ -4,7 +4,7 @@
from nbgrader.preprocessors import ClearSolutions
from glob import glob
from .preprocessors import RemoveCells, ClearCells, ConvertCells
from .utils import _check_nb_file
from .utils import _check_nb_file, _find_notebooks


class NotebookCleaner(object):
Expand Down Expand Up @@ -167,3 +167,13 @@ def save(self, path_save):
os.makedirs(dir_save)
nbf.write(self.ntbk, path_save)


def clear_notebooks(path, kind, skip=".ipynb_checkpoints", **kwargs):
notebooks = _find_notebooks(path, skip)
if len(notebooks) == 0:
print("Note: no notebooks were found to be cleared.")
for path in notebooks:
print(f"Clearing {kind} in {path}")
cleaner = NotebookCleaner(str(path))
cleaner.clear(kind, **kwargs)
cleaner.save(str(path))
41 changes: 2 additions & 39 deletions nbclean/cli.py
@@ -1,9 +1,8 @@
import click
import nbformat as nbf
from glob import glob
from nbclient import execute
from .clean import NotebookCleaner
from .run import run_notebook
from .clean import clear_notebooks
from .run import run_notebooks

@click.group()
def main():
Expand All @@ -17,44 +16,8 @@ def main():
def clear(path, kind, skip, **kwargs):
clear_notebooks(path, kind, skip=skip, **kwargs)

def _find_notebooks(path, skip):
from pathlib import Path
path = Path(path)
if not path.exists():
raise ValueError(f"You gave a path that doesn't exist: {path}")
elif path.is_dir():
notebooks = list(path.rglob("*.ipynb"))
notebooks = [ii for ii in notebooks if skip not in str(ii)]
elif path.suffix == ".ipynb":
notebooks = [str(path)]
else:
raise ValueError(f"You gave a path that isn't a folder or a notebook file: {path}")
return notebooks

def clear_notebooks(path, kind, skip=".ipynb_checkpoints", **kwargs):
notebooks = _find_notebooks(path, skip)
if len(notebooks) == 0:
print("Note: no notebooks were found to be cleared.")
for path in notebooks:
print(f"Clearing {kind} in {path}")
cleaner = NotebookCleaner(str(path))
cleaner.clear(kind, **kwargs)
cleaner.save(str(path))


@main.command()
@click.argument("path")
@click.option("--skip", default=".ipynb_checkpoints", help="What element of the notebooks you wish to clear")
def run(path, skip, **kwargs):
run_notebooks(path, skip, **kwargs)

def run_notebooks(path, skip, **kwargs):
notebooks = _find_notebooks(path, skip)
if len(notebooks) == 0:
print("Note: no notebooks were found to be executed.")

for path in notebooks:
print(f"Running {path}")
ntbk = nbf.read(str(path), nbf.NO_CONVERT)
ntbk = execute(ntbk, cwd=str(path.parent))
nbf.write(ntbk, str(path))
79 changes: 18 additions & 61 deletions nbclean/run.py
Expand Up @@ -2,65 +2,22 @@
import os
import os.path as op
from nbgrader.preprocessors import LimitOutput, Execute
from .utils import _check_nb_file
from .utils import _check_nb_file, _find_notebooks
from glob import glob
from pathlib import Path
from tqdm import tqdm
from nbclient import execute


def run_notebook_directory(path, path_save=None, max_output_lines=1000,
overwrite=False):
"""Run all the notebooks in a directory and save them somewhere else.
def run_notebooks(path, skip, **kwargs):
notebooks = _find_notebooks(path, skip)
if len(notebooks) == 0:
print("Note: no notebooks were found to be executed.")

Parameters
----------
path : str
A path to a directory that contains jupyter notebooks.
All notebooks in this folder ending in `.ipynb` will be run,
and the outputs will be placed in `path_save`. This may
optionally contain a wildcard matching ``<something>.ipynb`` in which
case only notebooks that match will be run.
path_save : str | None
A path to a directory to save the notebooks. If this doesn't exist,
it will be created. If `None`, notebooks will not be saved.
max_output_lines : int | None
The maximum number of lines allowed in notebook outputs.
overwrite : bool
Whether to overwrite the output directory if it exists.
Returns
-------
notebooks : list
A list of the `NotebookNode` instances, one for each notebook.
"""
if not op.exists(path):
raise ValueError("You've specified an input path that doesn't exist")
to_glob = op.join(path, '*.ipynb') if '.ipynb' not in path else path
notebooks = glob(to_glob)

# Execute notebooks
outputs = []
for notebook in tqdm(notebooks):
outputs.append(run_notebook(notebook,
max_output_lines=max_output_lines))

# Now save them
if path_save is not None:
print('Saving {} notebooks to: {}'.format(len(notebooks), path_save))
if not op.exists(path_save):
os.makedirs(path_save)
elif overwrite is True:
print('Overwriting output directory')
for ifile in glob(path_save + '*-exe.ipynb'):
os.remove(ifile)
else:
raise ValueError('path_save exists and overwrite is not True')

for filename, notebook in zip(notebooks, outputs):
this_name = op.basename(filename)
left, right = this_name.split('.')
left += '-exe'
this_name = '.'.join([left, right])
nbf.write(notebook, op.join(path_save, this_name))
for path in notebooks:
print(f"Running {path}")
ntbk = run_notebook(path)
nbf.write(ntbk, str(path))


def run_notebook(ntbk, max_output_lines=1000):
Expand All @@ -73,12 +30,12 @@ def run_notebook(ntbk, max_output_lines=1000):
max_output_lines : int | None
The maximum number of lines allowed in notebook outputs.
"""
if isinstance(ntbk, (str, type(Path))):
ntbk = Path(ntbk)
wd = str(ntbk.parent)
ntbk = str(ntbk)
else:
wd = str(Path())
ntbk = _check_nb_file(ntbk)

preprocessors = [Execute()]
if max_output_lines is not None:
preprocessors.append(LimitOutput(max_lines=max_output_lines,
max_traceback=max_output_lines))
for prep in preprocessors:
ntbk, _ = prep.preprocess(ntbk, {})
ntbk = execute(ntbk, cwd=wd)
return ntbk
51 changes: 2 additions & 49 deletions nbclean/tests/test_ntbk.ipynb
Expand Up @@ -14,31 +14,7 @@
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-0.1291054 0.12687936 -0.43424441 -0.42527338 -1.06042428 0.873431\n",
" -1.41487395 0.16180383 -0.36963902 -1.47040749 0.5380093 1.64442094\n",
" 0.01550058 -0.36913987 1.3185561 1.47267394 -0.24117057 -0.1868983\n",
" -2.39743438 1.97167598 -0.17841205 -0.52284158 -0.18303555 -0.00747752\n",
" 0.26361847 0.91230463 -1.17812049 -0.11316573 0.37338041 0.55512641\n",
" -0.72108943 1.6370304 -0.95906868 -0.32059531 -1.5615334 -1.07300787\n",
" 0.68033934 0.67717045 1.02077096 -0.15936002 -0.71579344 -1.18348182\n",
" -1.40105323 -0.09305708 -0.79004453 -0.83884275 -1.03279955 -1.50604434\n",
" -0.84528241 1.83662664 0.93372929 0.7034139 -0.43927167 0.06370446\n",
" 1.28176304 -0.3374127 -0.573012 -0.89501561 1.26972311 0.03706608\n",
" 0.38862378 0.64093822 0.64688551 0.9963434 0.53692001 0.33476171\n",
" 0.13735019 -1.04149315 0.63202144 -1.1908394 0.54666563 1.74715812\n",
" -1.10135633 -0.51360652 1.26403823 -1.24094441 1.50736803 0.10323768\n",
" -0.92334085 -1.66044892 -0.02672489 -0.06145144 0.96691626 -0.01344665\n",
" -1.26492364 1.33620823 -0.11632291 -2.2070902 -0.15912759 2.1311936\n",
" -0.56929863 -0.63117047 0.32744059 0.68677507 -0.28456693 0.48483996\n",
" -1.05184195 -0.80990045 -2.42788281 1.58669496]\n"
]
}
],
"outputs": [],
"source": [
"data = np.random.randn(2, 100)\n",
"print(data[0])"
Expand All @@ -48,30 +24,7 @@
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.collections.PathCollection at 0x7fe25a9ddb38>"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"outputs": [],
"source": [
"plt.scatter(*data)"
]
Expand Down
20 changes: 19 additions & 1 deletion nbclean/utils.py
@@ -1,12 +1,30 @@
import nbformat as nbf
from nbformat.notebooknode import NotebookNode
from copy import deepcopy
from pathlib import Path


def _check_nb_file(ntbk):
if isinstance(ntbk, Path):
ntbk = str(ntbk)
if isinstance(ntbk, str):
ntbk = nbf.read(ntbk, nbf.NO_CONVERT)
elif not isinstance(ntbk, NotebookNode):
raise TypeError('`ntbk` must be type string or `NotebookNode`')
raise TypeError(f'`ntbk` must be type string or `NotebookNode`, found: {type(ntbk)}')
ntbk = deepcopy(ntbk)
return ntbk


def _find_notebooks(path, skip):
from pathlib import Path
path = Path(path)
if not path.exists():
raise ValueError(f"You gave a path that doesn't exist: {path}")
elif path.is_dir():
notebooks = list(path.rglob("*.ipynb"))
notebooks = [ii for ii in notebooks if skip not in str(ii)]
elif path.suffix == ".ipynb":
notebooks = [str(path)]
else:
raise ValueError(f"You gave a path that isn't a folder or a notebook file: {path}")
return notebooks

0 comments on commit f1d5c15

Please sign in to comment.