1"""Python API for composing notebook elements
2
3The Python representation of a notebook is a nested structure of
4dictionary subclasses that support attribute access.
5The functions in this module are merely helpers to build the structs
6in the right form.
7"""
8
9# Copyright (c) IPython Development Team.
10# Distributed under the terms of the Modified BSD License.
11from __future__ import annotations
12
13from nbformat.corpus.words import generate_corpus_id as random_cell_id
14from nbformat.notebooknode import NotebookNode
15
16# Change the nbformat_minor and nbformat_schema variables when incrementing the
17# nbformat version
18
19# current major version
20nbformat = 4
21
22# current minor version
23nbformat_minor = 5
24
25# schema files for (major, minor) version tuples. (None, None) means the current version
26nbformat_schema = {
27 (None, None): "nbformat.v4.schema.json",
28 (4, 0): "nbformat.v4.0.schema.json",
29 (4, 1): "nbformat.v4.1.schema.json",
30 (4, 2): "nbformat.v4.2.schema.json",
31 (4, 3): "nbformat.v4.3.schema.json",
32 (4, 4): "nbformat.v4.4.schema.json",
33 (4, 5): "nbformat.v4.5.schema.json",
34}
35
36
37def validate(node, ref=None):
38 """validate a v4 node"""
39 from nbformat import validate as validate_orig
40
41 return validate_orig(node, ref=ref, version=nbformat)
42
43
44def new_output(output_type, data=None, **kwargs):
45 """Create a new output, to go in the ``cell.outputs`` list of a code cell."""
46 output = NotebookNode(output_type=output_type)
47
48 # populate defaults:
49 if output_type == "stream":
50 output.name = "stdout"
51 output.text = ""
52 elif output_type == "display_data":
53 output.metadata = NotebookNode()
54 output.data = NotebookNode()
55 elif output_type == "execute_result":
56 output.metadata = NotebookNode()
57 output.data = NotebookNode()
58 output.execution_count = None
59 elif output_type == "error":
60 output.ename = "NotImplementedError"
61 output.evalue = ""
62 output.traceback = []
63
64 # load from args:
65 output.update(kwargs)
66 if data is not None:
67 output.data = data
68 # validate
69 validate(output, output_type)
70 return output
71
72
73def output_from_msg(msg):
74 """Create a NotebookNode for an output from a kernel's IOPub message.
75
76 Returns
77 -------
78 NotebookNode: the output as a notebook node.
79
80 Raises
81 ------
82 ValueError: if the message is not an output message.
83
84 """
85 msg_type = msg["header"]["msg_type"]
86 content = msg["content"]
87
88 if msg_type == "execute_result":
89 return new_output(
90 output_type=msg_type,
91 metadata=content["metadata"],
92 data=content["data"],
93 execution_count=content["execution_count"],
94 )
95 if msg_type == "stream":
96 return new_output(
97 output_type=msg_type,
98 name=content["name"],
99 text=content["text"],
100 )
101 if msg_type == "display_data":
102 return new_output(
103 output_type=msg_type,
104 metadata=content["metadata"],
105 data=content["data"],
106 )
107 if msg_type == "error":
108 return new_output(
109 output_type=msg_type,
110 ename=content["ename"],
111 evalue=content["evalue"],
112 traceback=content["traceback"],
113 )
114 raise ValueError("Unrecognized output msg type: %r" % msg_type)
115
116
117def new_code_cell(source="", **kwargs):
118 """Create a new code cell"""
119 cell = NotebookNode(
120 id=random_cell_id(),
121 cell_type="code",
122 metadata=NotebookNode(),
123 execution_count=None,
124 source=source,
125 outputs=[],
126 )
127 cell.update(kwargs)
128
129 validate(cell, "code_cell")
130 return cell
131
132
133def new_markdown_cell(source="", **kwargs):
134 """Create a new markdown cell"""
135 cell = NotebookNode(
136 id=random_cell_id(),
137 cell_type="markdown",
138 source=source,
139 metadata=NotebookNode(),
140 )
141 cell.update(kwargs)
142
143 validate(cell, "markdown_cell")
144 return cell
145
146
147def new_raw_cell(source="", **kwargs):
148 """Create a new raw cell"""
149 cell = NotebookNode(
150 id=random_cell_id(),
151 cell_type="raw",
152 source=source,
153 metadata=NotebookNode(),
154 )
155 cell.update(kwargs)
156
157 validate(cell, "raw_cell")
158 return cell
159
160
161def new_notebook(**kwargs):
162 """Create a new notebook"""
163 nb = NotebookNode(
164 nbformat=nbformat,
165 nbformat_minor=nbformat_minor,
166 metadata=NotebookNode(),
167 cells=[],
168 )
169 nb.update(kwargs)
170 validate(nb)
171 return nb