Source code for nbtoolbelt.nbdumpapp
"""
Tool nbdump; dump cell sources of notebooks
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
from nbformat import NotebookNode
from nbtoolbelt.arguments import NegatableAction, split_csv, join_csv
from nbtoolbelt.counting import REQUIRED_CELL_FIELDS, nb_other_metadata
from nbtoolbelt.processing import ProcessingResultType
from nbtoolbelt.toolbaseapp import Tool
TOOL = 'dump'
[docs]class DumpTool(Tool):
"""Show all source lines of each notebook.
"""
def __init__(self) -> None:
super().__init__(
name='nb' + TOOL,
description='Dump cell sources of Jupyter notebooks.',
action=TOOL
)
[docs] def process_nb(self, nb: NotebookNode, nb_path: Path) -> ProcessingResultType:
"""Dump cell sources of notebook.
:param nb: notebook to dump
:param nb_path: notebook's path
:return: empty result
"""
info_prefix = self._args.dump_info_prefix
line_indent = ' ' * self._args.dump_source_line_indent
cell_spacing = '\n' * self._args.dump_cell_spacing
if self._args.dump_notebook_info:
print('{} nbformat: {:1d}.{:1d}'
.format(info_prefix, nb.get('nbformat', 1), nb.get('nbformat_minor', 0)), end='')
if 'kernelspec' in nb.metadata:
print(' | kernel: {}'.format(nb.metadata.kernelspec.name), end='')
if 'language_info' in nb.metadata:
l_i = nb.metadata.language_info
print(' | language: {} {}'.format(l_i.name, l_i.version), end='')
print(' {}'.format(info_prefix))
print('{} cells: {}'.format(info_prefix, len(nb.cells)), end='')
other_metadata = nb_other_metadata(nb)
if other_metadata:
print(' | metadata: {}'.format(join_csv(other_metadata.keys())), end='')
print(' {}'.format(info_prefix))
spacing = ''
for index, cell in enumerate(nb.cells):
ct = cell.cell_type
if ct in self._args.dump_cell_types:
print(spacing, end='')
spacing = cell_spacing
if self._args.dump_cell_info:
print('{} cell {}: {}'.format(info_prefix, index, ct), end='')
metadata = set(cell.metadata.keys())
metadata.discard('tags')
if metadata:
print(' | metadata: {}'.format(','.join(metadata)), end='')
if 'tags' in cell.metadata:
tags = ','.join(cell.metadata.tags)
print(' | tags: {}'.format(tags), end='')
if (ct == 'markdown' or ct == 'raw') and 'attachments' in cell:
print(' | attachments: {}'.format(len(cell.attachments)), end='')
if ct == 'code' and cell.outputs:
print(' | outputs: {}'.format(len(cell.outputs)), end='')
print(' {}'.format(info_prefix))
if self._args.dump_sources and cell.source:
for line_index, line in enumerate(cell.source.split('\n')):
if self._args.dump_source_line_numbers:
print('{}{:>2}| {}'.format(line_indent, line_index + 1, line), sep='')
else:
print('{}{}'.format(line_indent, line), sep='')
return [] # no notebooks produced
[docs] def config_tool_args_parsing(self, group: _ArgumentGroup) -> None:
group.add_argument('-g', '--notebook-info',
action=NegatableAction, default=SUPPRESS, dest='dump_notebook_info',
help='show global notebook information' +
' (default: {})'.format(self._args.dump_notebook_info))
group.add_argument('-c', '--cell-info',
action=NegatableAction, default=SUPPRESS, dest='dump_cell_info',
help='show cell information' +
' (default: {})'.format(self._args.dump_cell_info))
group.add_argument('-s', '--sources',
action=NegatableAction, default=SUPPRESS, dest='dump_sources',
help='show cell sources' +
' (default: {})'.format(self._args.dump_sources))
group.add_argument('-t', '--cell-types', default=SUPPRESS, type=split_csv, dest='dump_cell_types',
metavar='TYPES',
help='comma-separated list of cell types to dump' +
" (default: '{}')".format(join_csv(self._args.dump_cell_types)))
group.add_argument('-p', '--prefix',
default=SUPPRESS, dest='dump_info_prefix', metavar='STRING',
help='pre/postfix for information lines' +
" (default: '{}')".format(self._args.dump_info_prefix))
group.add_argument('-i', '--indent',
default=SUPPRESS, type=int, dest='dump_source_line_indent', metavar='INT',
help='indentation level for source lines' +
' (default: {})'.format(self._args.dump_source_line_indent))
group.add_argument('-l', '--line-numbers',
action=NegatableAction, default=SUPPRESS, dest='dump_source_line_numbers',
help='show source line numbers' +
' (default: {})'.format(self._args.dump_source_line_numbers))
group.add_argument('-e', '--cell-spacing',
default=SUPPRESS, type=int, dest='dump_cell_spacing', metavar='INT',
help='number of empty lines between cells' +
' (default: {})'.format(self._args.dump_cell_spacing))
[docs] def check_and_adjust_arguments(self) -> None:
bad = set(self._args.dump_cell_types).difference(REQUIRED_CELL_FIELDS.keys())
if bad:
raise ValueError('Invalid cell types with -t: {}'.format(join_csv(bad)))
[docs] def print_tool_args(self) -> None:
print(' Dump notebook info: {}'.format(self._args.dump_notebook_info))
print(' Dump cell info: {}'.format(self._args.dump_cell_info))
print(' Dump cell sources: {}'.format(self._args.dump_sources))
print(' Dump cell types: {}'.format(join_csv(self._args.dump_cell_types)))
print(' Prefix for information lines: {}'.format(self._args.dump_info_prefix))
print(' Source line indentation level: {}'.format(self._args.dump_source_line_indent))
print(' Show source line numbers: {}'.format(self._args.dump_source_line_numbers))
print(' Cell spacing lines: {}'.format(self._args.dump_cell_spacing))
if __name__ == "__main__":
import sys
sys.exit(main())