Source code for nbtoolbelt.nbcleanapp
"""
Main for nbclean
Copyright (c) 2017 - Eindhoven University of Technology, The Netherlands
This software is made available under the terms of the MIT License.
"""
from argparse import _ArgumentGroup, SUPPRESS
from pathlib import Path
from typing import Optional, List, Set
from nbformat import NotebookNode
from nbtoolbelt.arguments import split_csv, NegatableAction, join_csv
from nbtoolbelt.cleaning import clean_nb
from nbtoolbelt.counting import REQUIRED_NB_METADATA_FIELDS
from nbtoolbelt.printing import print_dict
from nbtoolbelt.processing import ProcessingResultType
from nbtoolbelt.toolbaseapp import Tool
TOOL = 'clean'
[docs]class CleanTool(Tool):
"""Clean each notebook.
"""
def __init__(self) -> None:
super().__init__(
name='nb' + TOOL,
action=TOOL,
description="""Clean Jupyter notebooks by deleting or resetting selected elements."""
)
[docs] def process_nb(self, nb: NotebookNode, nb_path: Path) -> ProcessingResultType:
"""Clean notebook nb.
.. note:: **Modifies**: ``nb``
:param nb: notebook to clean
:param nb_path: path to ``nb``
:return: sequence of resulting (notebook, notebook-path) pairs
"""
args = self._args
# do the cleaning, and collect some statistics
freq = clean_nb(nb, args)
# show statistics
if not args.quiet:
print_dict(freq, 'Cleaning counts')
self._aggregate['outputs'][-1].update(freq)
# set up destination path
if args.inplace:
nb_clean_path = nb_path
else:
nb_clean_path = nb_path.with_name(nb_path.stem + args.clean_result_name + nb_path.suffix)
if args.debug:
print('Clean destination:', nb_clean_path)
return [(nb, nb_clean_path)]
[docs] def config_tool_args_parsing(self, group: _ArgumentGroup) -> None:
group.add_argument('-g', '--global',
dest='clean_notebook_metadata_fields', default=SUPPRESS, type=split_csv,
metavar='FIELDS',
help='comma-separated list of fields to remove from metadata of notebook' +
" (default: '{}')".format(join_csv(self._args.clean_notebook_metadata_fields)))
group.add_argument('-m', '--metadata',
dest='clean_cell_metadata_fields', default=SUPPRESS, type=split_csv,
metavar='FIELDS',
help='comma-separated list of fields to remove from metadata of all cells' +
" (default: '{}')".format(join_csv(self._args.clean_cell_metadata_fields)))
group.add_argument('-t', '--tags', dest='clean_tags', default=SUPPRESS, type=split_csv,
metavar='TAGS',
help='comma-separated list of tags to remove from all cells;'
" use '-m tags' to remove all tags" +
" (default: '{}')".format(join_csv(self._args.clean_tags)))
group.add_argument('-e', '--empty-cells',
action=NegatableAction, dest='clean_empty_cells', default=SUPPRESS,
help='delete cells with empty source, i.e. with whitespace only' +
' (default: {})'.format(self._args.clean_empty_cells))
group.add_argument('-o', '--outputs',
action=NegatableAction, dest='clean_outputs', default=SUPPRESS,
help='clean all outputs from all code cells ' +
' (default: {})'.format(self._args.clean_outputs))
[docs] def check_and_adjust_arguments(self):
args = self._args
nmf = set(args.clean_notebook_metadata_fields) # type: Set[str]
if nmf:
intersection = nmf.intersection(REQUIRED_NB_METADATA_FIELDS)
if intersection:
print('WARNING: {} are required notebook metadata fields'.format(intersection))
print(' These will not be cleaned')
nmf.difference_update(REQUIRED_NB_METADATA_FIELDS)
[docs] def print_tool_args(self) -> None:
args = self._args
if args.clean_notebook_metadata_fields:
print(" Deleting notebook metadata fields: {}".format(args.clean_notebook_metadata_fields))
if args.clean_cell_metadata_fields:
print(" Deleting cell metadata fields: {}".format(args.clean_cell_metadata_fields))
if args.clean_tags:
print(" Deleting tags: {}".format(args.clean_tags))
if args.clean_empty_cells:
print(' Deleting cells with empty source')
if args.clean_outputs:
print(' Deleting outputs from all code cells')
if __name__ == "__main__":
import sys
sys.exit(main())