|
|
"""Python API for composing notebook elements
|
|
|
|
|
|
The Python representation of a notebook is a nested structure of
|
|
|
dictionary subclasses that support attribute access
|
|
|
(IPython.utils.ipstruct.Struct). The functions in this module are merely
|
|
|
helpers to build the structs in the right form.
|
|
|
"""
|
|
|
|
|
|
# Copyright (c) IPython Development Team.
|
|
|
# Distributed under the terms of the Modified BSD License.
|
|
|
|
|
|
from IPython.utils.ipstruct import Struct
|
|
|
|
|
|
# Change this when incrementing the nbformat version
|
|
|
nbformat = 4
|
|
|
nbformat_minor = 0
|
|
|
nbformat_schema = 'nbformat.v4.schema.json'
|
|
|
|
|
|
|
|
|
def validate(node, ref=None):
|
|
|
"""validate a v4 node"""
|
|
|
from ..current import validate
|
|
|
return validate(node, ref=ref, version=nbformat)
|
|
|
|
|
|
|
|
|
class NotebookNode(Struct):
|
|
|
pass
|
|
|
|
|
|
def from_dict(d):
|
|
|
if isinstance(d, dict):
|
|
|
newd = NotebookNode()
|
|
|
for k,v in d.items():
|
|
|
newd[k] = from_dict(v)
|
|
|
return newd
|
|
|
elif isinstance(d, (tuple, list)):
|
|
|
return [from_dict(i) for i in d]
|
|
|
else:
|
|
|
return d
|
|
|
|
|
|
|
|
|
def new_output(output_type, data=None, **kwargs):
|
|
|
"""Create a new output, to go in the ``cell.outputs`` list of a code cell."""
|
|
|
output = NotebookNode(output_type=output_type)
|
|
|
output.update(from_dict(kwargs))
|
|
|
if data is not None:
|
|
|
output.data = from_dict(data)
|
|
|
|
|
|
# populate defaults:
|
|
|
if output_type == 'stream':
|
|
|
output.setdefault('name', 'stdout')
|
|
|
output.setdefault('text', '')
|
|
|
elif output_type in {'execute_result', 'display_data'}:
|
|
|
output.setdefault('metadata', NotebookNode())
|
|
|
output.setdefault('data', NotebookNode())
|
|
|
validate(output, output_type)
|
|
|
return output
|
|
|
|
|
|
|
|
|
def output_from_msg(msg):
|
|
|
"""Create a NotebookNode for an output from a kernel's IOPub message.
|
|
|
|
|
|
Returns
|
|
|
-------
|
|
|
|
|
|
NotebookNode: the output as a notebook node.
|
|
|
|
|
|
Raises
|
|
|
------
|
|
|
|
|
|
ValueError: if the message is not an output message.
|
|
|
|
|
|
"""
|
|
|
msg_type = msg['header']['msg_type']
|
|
|
content = msg['content']
|
|
|
|
|
|
if msg_type == 'execute_result':
|
|
|
return new_output(output_type=msg_type,
|
|
|
metadata=content['metadata'],
|
|
|
data=content['data'],
|
|
|
execution_count=content['execution_count'],
|
|
|
)
|
|
|
|
|
|
elif msg_type == 'stream':
|
|
|
return new_output(output_type=msg_type,
|
|
|
name=content['name'],
|
|
|
text=content['text'],
|
|
|
)
|
|
|
elif msg_type == 'display_data':
|
|
|
return new_output(output_type=msg_type,
|
|
|
metadata=content['metadata'],
|
|
|
data=content['data'],
|
|
|
)
|
|
|
elif msg_type == 'error':
|
|
|
return new_output(output_type=msg_type,
|
|
|
ename=content['ename'],
|
|
|
evalue=content['evalue'],
|
|
|
traceback=content['traceback'],
|
|
|
)
|
|
|
else:
|
|
|
raise ValueError("Unrecognized output msg type: %r" % msg_type)
|
|
|
|
|
|
|
|
|
def new_code_cell(source='', **kwargs):
|
|
|
"""Create a new code cell"""
|
|
|
cell = NotebookNode(cell_type='code', source=source)
|
|
|
cell.update(from_dict(kwargs))
|
|
|
cell.setdefault('metadata', NotebookNode())
|
|
|
cell.setdefault('source', '')
|
|
|
cell.setdefault('execution_count', None)
|
|
|
cell.setdefault('outputs', [])
|
|
|
|
|
|
validate(cell, 'code_cell')
|
|
|
return cell
|
|
|
|
|
|
def new_markdown_cell(source='', **kwargs):
|
|
|
"""Create a new markdown cell"""
|
|
|
cell = NotebookNode(cell_type='markdown', source=source)
|
|
|
cell.update(from_dict(kwargs))
|
|
|
cell.setdefault('metadata', NotebookNode())
|
|
|
|
|
|
validate(cell, 'markdown_cell')
|
|
|
return cell
|
|
|
|
|
|
def new_heading_cell(source='', **kwargs):
|
|
|
"""Create a new heading cell"""
|
|
|
cell = NotebookNode(cell_type='heading', source=source)
|
|
|
cell.update(from_dict(kwargs))
|
|
|
cell.setdefault('metadata', NotebookNode())
|
|
|
cell.setdefault('level', 1)
|
|
|
|
|
|
validate(cell, 'heading_cell')
|
|
|
return cell
|
|
|
|
|
|
def new_raw_cell(source='', **kwargs):
|
|
|
"""Create a new raw cell"""
|
|
|
cell = NotebookNode(cell_type='raw', source=source)
|
|
|
cell.update(from_dict(kwargs))
|
|
|
cell.setdefault('metadata', NotebookNode())
|
|
|
|
|
|
validate(cell, 'raw_cell')
|
|
|
return cell
|
|
|
|
|
|
def new_notebook(**kwargs):
|
|
|
"""Create a new notebook"""
|
|
|
nb = from_dict(kwargs)
|
|
|
nb.nbformat = nbformat
|
|
|
nb.nbformat_minor = nbformat_minor
|
|
|
nb.setdefault('cells', [])
|
|
|
nb.setdefault('metadata', NotebookNode())
|
|
|
validate(nb)
|
|
|
return nb
|
|
|
|