##// END OF EJS Templates
output_type should not be optional in new_output...
MinRK -
Show More
@@ -1,129 +1,129
1 1 # coding: utf-8
2 2 import base64
3 3 import io
4 4 import json
5 5 import os
6 6 from os.path import join as pjoin
7 7 import shutil
8 8
9 9 import requests
10 10
11 11 from IPython.html.utils import url_path_join
12 12 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
13 13 from IPython.nbformat.current import (new_notebook, write, new_worksheet,
14 14 new_heading_cell, new_code_cell,
15 15 new_output)
16 16
17 17 from IPython.testing.decorators import onlyif_cmds_exist
18 18
19 19
20 20 class NbconvertAPI(object):
21 21 """Wrapper for nbconvert API calls."""
22 22 def __init__(self, base_url):
23 23 self.base_url = base_url
24 24
25 25 def _req(self, verb, path, body=None, params=None):
26 26 response = requests.request(verb,
27 27 url_path_join(self.base_url, 'nbconvert', path),
28 28 data=body, params=params,
29 29 )
30 30 response.raise_for_status()
31 31 return response
32 32
33 33 def from_file(self, format, path, name, download=False):
34 34 return self._req('GET', url_path_join(format, path, name),
35 35 params={'download':download})
36 36
37 37 def from_post(self, format, nbmodel):
38 38 body = json.dumps(nbmodel)
39 39 return self._req('POST', format, body)
40 40
41 41 def list_formats(self):
42 42 return self._req('GET', '')
43 43
44 44 png_green_pixel = base64.encodestring(b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00'
45 45 b'\x00\x00\x01\x00\x00x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\x0cIDAT'
46 46 b'\x08\xd7c\x90\xfb\xcf\x00\x00\x02\\\x01\x1e.~d\x87\x00\x00\x00\x00IEND\xaeB`\x82')
47 47
48 48 class APITest(NotebookTestBase):
49 49 def setUp(self):
50 50 nbdir = self.notebook_dir.name
51 51
52 52 if not os.path.isdir(pjoin(nbdir, 'foo')):
53 53 os.mkdir(pjoin(nbdir, 'foo'))
54 54
55 55 nb = new_notebook(name='testnb')
56 56
57 57 ws = new_worksheet()
58 58 nb.worksheets = [ws]
59 59 ws.cells.append(new_heading_cell(u'Created by test Β³'))
60 60 cc1 = new_code_cell(input=u'print(2*6)')
61 cc1.outputs.append(new_output(output_text=u'12'))
61 cc1.outputs.append(new_output(output_text=u'12', output_type='stream'))
62 62 cc1.outputs.append(new_output(output_png=png_green_pixel, output_type='pyout'))
63 63 ws.cells.append(cc1)
64 64
65 65 with io.open(pjoin(nbdir, 'foo', 'testnb.ipynb'), 'w',
66 66 encoding='utf-8') as f:
67 67 write(nb, f, format='ipynb')
68 68
69 69 self.nbconvert_api = NbconvertAPI(self.base_url())
70 70
71 71 def tearDown(self):
72 72 nbdir = self.notebook_dir.name
73 73
74 74 for dname in ['foo']:
75 75 shutil.rmtree(pjoin(nbdir, dname), ignore_errors=True)
76 76
77 77 @onlyif_cmds_exist('pandoc')
78 78 def test_from_file(self):
79 79 r = self.nbconvert_api.from_file('html', 'foo', 'testnb.ipynb')
80 80 self.assertEqual(r.status_code, 200)
81 81 self.assertIn(u'text/html', r.headers['Content-Type'])
82 82 self.assertIn(u'Created by test', r.text)
83 83 self.assertIn(u'print', r.text)
84 84
85 85 r = self.nbconvert_api.from_file('python', 'foo', 'testnb.ipynb')
86 86 self.assertIn(u'text/x-python', r.headers['Content-Type'])
87 87 self.assertIn(u'print(2*6)', r.text)
88 88
89 89 @onlyif_cmds_exist('pandoc')
90 90 def test_from_file_404(self):
91 91 with assert_http_error(404):
92 92 self.nbconvert_api.from_file('html', 'foo', 'thisdoesntexist.ipynb')
93 93
94 94 @onlyif_cmds_exist('pandoc')
95 95 def test_from_file_download(self):
96 96 r = self.nbconvert_api.from_file('python', 'foo', 'testnb.ipynb', download=True)
97 97 content_disposition = r.headers['Content-Disposition']
98 98 self.assertIn('attachment', content_disposition)
99 99 self.assertIn('testnb.py', content_disposition)
100 100
101 101 @onlyif_cmds_exist('pandoc')
102 102 def test_from_file_zip(self):
103 103 r = self.nbconvert_api.from_file('latex', 'foo', 'testnb.ipynb', download=True)
104 104 self.assertIn(u'application/zip', r.headers['Content-Type'])
105 105 self.assertIn(u'.zip', r.headers['Content-Disposition'])
106 106
107 107 @onlyif_cmds_exist('pandoc')
108 108 def test_from_post(self):
109 109 nbmodel_url = url_path_join(self.base_url(), 'api/notebooks/foo/testnb.ipynb')
110 110 nbmodel = requests.get(nbmodel_url).json()
111 111
112 112 r = self.nbconvert_api.from_post(format='html', nbmodel=nbmodel)
113 113 self.assertEqual(r.status_code, 200)
114 114 self.assertIn(u'text/html', r.headers['Content-Type'])
115 115 self.assertIn(u'Created by test', r.text)
116 116 self.assertIn(u'print', r.text)
117 117
118 118 r = self.nbconvert_api.from_post(format='python', nbmodel=nbmodel)
119 119 self.assertIn(u'text/x-python', r.headers['Content-Type'])
120 120 self.assertIn(u'print(2*6)', r.text)
121 121
122 122 @onlyif_cmds_exist('pandoc')
123 123 def test_from_post_zip(self):
124 124 nbmodel_url = url_path_join(self.base_url(), 'api/notebooks/foo/testnb.ipynb')
125 125 nbmodel = requests.get(nbmodel_url).json()
126 126
127 127 r = self.nbconvert_api.from_post(format='latex', nbmodel=nbmodel)
128 128 self.assertIn(u'application/zip', r.headers['Content-Type'])
129 129 self.assertIn(u'.zip', r.headers['Content-Disposition'])
@@ -1,217 +1,204
1 1 """The basic dict based notebook format.
2 2
3 3 The Python representation of a notebook is a nested structure of
4 4 dictionary subclasses that support attribute access
5 5 (IPython.utils.ipstruct.Struct). The functions in this module are merely
6 6 helpers to build the structs in the right form.
7
8 Authors:
9
10 * Brian Granger
11 7 """
12 8
13 #-----------------------------------------------------------------------------
14 # Copyright (C) 2008-2011 The IPython Development Team
15 #
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
18 #-----------------------------------------------------------------------------
19
20 #-----------------------------------------------------------------------------
21 # Imports
22 #-----------------------------------------------------------------------------
9 # Copyright (c) IPython Development Team.
10 # Distributed under the terms of the Modified BSD License.
23 11
24 12 import pprint
25 13 import uuid
26 14
27 15 from IPython.utils.ipstruct import Struct
28 16 from IPython.utils.py3compat import cast_unicode, unicode_type
29 17
30 18 #-----------------------------------------------------------------------------
31 19 # Code
32 20 #-----------------------------------------------------------------------------
33 21
34 22 # Change this when incrementing the nbformat version
35 23 nbformat = 3
36 24 nbformat_minor = 0
37 25
38 26 class NotebookNode(Struct):
39 27 pass
40 28
41 29
42 30 def from_dict(d):
43 31 if isinstance(d, dict):
44 32 newd = NotebookNode()
45 33 for k,v in d.items():
46 34 newd[k] = from_dict(v)
47 35 return newd
48 36 elif isinstance(d, (tuple, list)):
49 37 return [from_dict(i) for i in d]
50 38 else:
51 39 return d
52 40
53 41
54 def new_output(output_type=None, output_text=None, output_png=None,
42 def new_output(output_type, output_text=None, output_png=None,
55 43 output_html=None, output_svg=None, output_latex=None, output_json=None,
56 44 output_javascript=None, output_jpeg=None, prompt_number=None,
57 45 ename=None, evalue=None, traceback=None, stream=None, metadata=None):
58 46 """Create a new output, to go in the ``cell.outputs`` list of a code cell.
59 47 """
60 48 output = NotebookNode()
61 if output_type is not None:
62 output.output_type = unicode_type(output_type)
49 output.output_type = unicode_type(output_type)
63 50
64 51 if metadata is None:
65 52 metadata = {}
66 53 if not isinstance(metadata, dict):
67 54 raise TypeError("metadata must be dict")
68 55 output.metadata = metadata
69 56
70 57 if output_type != 'pyerr':
71 58 if output_text is not None:
72 59 output.text = cast_unicode(output_text)
73 60 if output_png is not None:
74 61 output.png = cast_unicode(output_png)
75 62 if output_jpeg is not None:
76 63 output.jpeg = cast_unicode(output_jpeg)
77 64 if output_html is not None:
78 65 output.html = cast_unicode(output_html)
79 66 if output_svg is not None:
80 67 output.svg = cast_unicode(output_svg)
81 68 if output_latex is not None:
82 69 output.latex = cast_unicode(output_latex)
83 70 if output_json is not None:
84 71 output.json = cast_unicode(output_json)
85 72 if output_javascript is not None:
86 73 output.javascript = cast_unicode(output_javascript)
87 74
88 75 if output_type == u'pyout':
89 76 if prompt_number is not None:
90 77 output.prompt_number = int(prompt_number)
91 78
92 79 if output_type == u'pyerr':
93 80 if ename is not None:
94 81 output.ename = cast_unicode(ename)
95 82 if evalue is not None:
96 83 output.evalue = cast_unicode(evalue)
97 84 if traceback is not None:
98 85 output.traceback = [cast_unicode(frame) for frame in list(traceback)]
99 86
100 87 if output_type == u'stream':
101 88 output.stream = 'stdout' if stream is None else cast_unicode(stream)
102 89
103 90 return output
104 91
105 92
106 93 def new_code_cell(input=None, prompt_number=None, outputs=None,
107 94 language=u'python', collapsed=False, metadata=None):
108 95 """Create a new code cell with input and output"""
109 96 cell = NotebookNode()
110 97 cell.cell_type = u'code'
111 98 if language is not None:
112 99 cell.language = cast_unicode(language)
113 100 if input is not None:
114 101 cell.input = cast_unicode(input)
115 102 if prompt_number is not None:
116 103 cell.prompt_number = int(prompt_number)
117 104 if outputs is None:
118 105 cell.outputs = []
119 106 else:
120 107 cell.outputs = outputs
121 108 if collapsed is not None:
122 109 cell.collapsed = bool(collapsed)
123 110 cell.metadata = NotebookNode(metadata or {})
124 111
125 112 return cell
126 113
127 114 def new_text_cell(cell_type, source=None, rendered=None, metadata=None):
128 115 """Create a new text cell."""
129 116 cell = NotebookNode()
130 117 # VERSIONHACK: plaintext -> raw
131 118 # handle never-released plaintext name for raw cells
132 119 if cell_type == 'plaintext':
133 120 cell_type = 'raw'
134 121 if source is not None:
135 122 cell.source = cast_unicode(source)
136 123 if rendered is not None:
137 124 cell.rendered = cast_unicode(rendered)
138 125 cell.metadata = NotebookNode(metadata or {})
139 126 cell.cell_type = cell_type
140 127 return cell
141 128
142 129
143 130 def new_heading_cell(source=None, rendered=None, level=1, metadata=None):
144 131 """Create a new section cell with a given integer level."""
145 132 cell = NotebookNode()
146 133 cell.cell_type = u'heading'
147 134 if source is not None:
148 135 cell.source = cast_unicode(source)
149 136 if rendered is not None:
150 137 cell.rendered = cast_unicode(rendered)
151 138 cell.level = int(level)
152 139 cell.metadata = NotebookNode(metadata or {})
153 140 return cell
154 141
155 142
156 143 def new_worksheet(name=None, cells=None, metadata=None):
157 144 """Create a worksheet by name with with a list of cells."""
158 145 ws = NotebookNode()
159 146 if name is not None:
160 147 ws.name = cast_unicode(name)
161 148 if cells is None:
162 149 ws.cells = []
163 150 else:
164 151 ws.cells = list(cells)
165 152 ws.metadata = NotebookNode(metadata or {})
166 153 return ws
167 154
168 155
169 156 def new_notebook(name=None, metadata=None, worksheets=None):
170 157 """Create a notebook by name, id and a list of worksheets."""
171 158 nb = NotebookNode()
172 159 nb.nbformat = nbformat
173 160 nb.nbformat_minor = nbformat_minor
174 161 if worksheets is None:
175 162 nb.worksheets = []
176 163 else:
177 164 nb.worksheets = list(worksheets)
178 165 if metadata is None:
179 166 nb.metadata = new_metadata()
180 167 else:
181 168 nb.metadata = NotebookNode(metadata)
182 169 if name is not None:
183 170 nb.metadata.name = cast_unicode(name)
184 171 return nb
185 172
186 173
187 174 def new_metadata(name=None, authors=None, license=None, created=None,
188 175 modified=None, gistid=None):
189 176 """Create a new metadata node."""
190 177 metadata = NotebookNode()
191 178 if name is not None:
192 179 metadata.name = cast_unicode(name)
193 180 if authors is not None:
194 181 metadata.authors = list(authors)
195 182 if created is not None:
196 183 metadata.created = cast_unicode(created)
197 184 if modified is not None:
198 185 metadata.modified = cast_unicode(modified)
199 186 if license is not None:
200 187 metadata.license = cast_unicode(license)
201 188 if gistid is not None:
202 189 metadata.gistid = cast_unicode(gistid)
203 190 return metadata
204 191
205 192 def new_author(name=None, email=None, affiliation=None, url=None):
206 193 """Create a new author."""
207 194 author = NotebookNode()
208 195 if name is not None:
209 196 author.name = cast_unicode(name)
210 197 if email is not None:
211 198 author.email = cast_unicode(email)
212 199 if affiliation is not None:
213 200 author.affiliation = cast_unicode(affiliation)
214 201 if url is not None:
215 202 author.url = cast_unicode(url)
216 203 return author
217 204
@@ -1,157 +1,157
1 1 from unittest import TestCase
2 2
3 3 from ..nbbase import (
4 4 NotebookNode,
5 5 new_code_cell, new_text_cell, new_worksheet, new_notebook, new_output,
6 6 new_author, new_metadata, new_heading_cell, nbformat
7 7 )
8 8
9 9 class TestCell(TestCase):
10 10
11 11 def test_empty_code_cell(self):
12 12 cc = new_code_cell()
13 13 self.assertEqual(cc.cell_type,u'code')
14 14 self.assertEqual(u'input' not in cc, True)
15 15 self.assertEqual(u'prompt_number' not in cc, True)
16 16 self.assertEqual(cc.outputs, [])
17 17 self.assertEqual(cc.collapsed, False)
18 18
19 19 def test_code_cell(self):
20 20 cc = new_code_cell(input='a=10', prompt_number=0, collapsed=True)
21 21 cc.outputs = [new_output(output_type=u'pyout',
22 22 output_svg=u'foo',output_text=u'10',prompt_number=0)]
23 23 self.assertEqual(cc.input, u'a=10')
24 24 self.assertEqual(cc.prompt_number, 0)
25 25 self.assertEqual(cc.language, u'python')
26 26 self.assertEqual(cc.outputs[0].svg, u'foo')
27 27 self.assertEqual(cc.outputs[0].text, u'10')
28 28 self.assertEqual(cc.outputs[0].prompt_number, 0)
29 29 self.assertEqual(cc.collapsed, True)
30 30
31 31 def test_pyerr(self):
32 32 o = new_output(output_type=u'pyerr', ename=u'NameError',
33 33 evalue=u'Name not found', traceback=[u'frame 0', u'frame 1', u'frame 2']
34 34 )
35 35 self.assertEqual(o.output_type, u'pyerr')
36 36 self.assertEqual(o.ename, u'NameError')
37 37 self.assertEqual(o.evalue, u'Name not found')
38 38 self.assertEqual(o.traceback, [u'frame 0', u'frame 1', u'frame 2'])
39 39
40 40 def test_empty_html_cell(self):
41 41 tc = new_text_cell(u'html')
42 42 self.assertEqual(tc.cell_type, u'html')
43 43 self.assertEqual(u'source' not in tc, True)
44 44 self.assertEqual(u'rendered' not in tc, True)
45 45
46 46 def test_html_cell(self):
47 47 tc = new_text_cell(u'html', 'hi', 'hi')
48 48 self.assertEqual(tc.source, u'hi')
49 49 self.assertEqual(tc.rendered, u'hi')
50 50
51 51 def test_empty_markdown_cell(self):
52 52 tc = new_text_cell(u'markdown')
53 53 self.assertEqual(tc.cell_type, u'markdown')
54 54 self.assertEqual(u'source' not in tc, True)
55 55 self.assertEqual(u'rendered' not in tc, True)
56 56
57 57 def test_markdown_cell(self):
58 58 tc = new_text_cell(u'markdown', 'hi', 'hi')
59 59 self.assertEqual(tc.source, u'hi')
60 60 self.assertEqual(tc.rendered, u'hi')
61 61
62 62 def test_empty_raw_cell(self):
63 63 tc = new_text_cell(u'raw')
64 64 self.assertEqual(tc.cell_type, u'raw')
65 65 self.assertEqual(u'source' not in tc, True)
66 66 self.assertEqual(u'rendered' not in tc, True)
67 67
68 68 def test_raw_cell(self):
69 69 tc = new_text_cell(u'raw', 'hi', 'hi')
70 70 self.assertEqual(tc.source, u'hi')
71 71 self.assertEqual(tc.rendered, u'hi')
72 72
73 73 def test_empty_heading_cell(self):
74 74 tc = new_heading_cell()
75 75 self.assertEqual(tc.cell_type, u'heading')
76 76 self.assertEqual(u'source' not in tc, True)
77 77 self.assertEqual(u'rendered' not in tc, True)
78 78
79 79 def test_heading_cell(self):
80 80 tc = new_heading_cell(u'hi', u'hi', level=2)
81 81 self.assertEqual(tc.source, u'hi')
82 82 self.assertEqual(tc.rendered, u'hi')
83 83 self.assertEqual(tc.level, 2)
84 84
85 85
86 86 class TestWorksheet(TestCase):
87 87
88 88 def test_empty_worksheet(self):
89 89 ws = new_worksheet()
90 90 self.assertEqual(ws.cells,[])
91 91 self.assertEqual(u'name' not in ws, True)
92 92
93 93 def test_worksheet(self):
94 94 cells = [new_code_cell(), new_text_cell(u'html')]
95 95 ws = new_worksheet(cells=cells,name=u'foo')
96 96 self.assertEqual(ws.cells,cells)
97 97 self.assertEqual(ws.name,u'foo')
98 98
99 99 class TestNotebook(TestCase):
100 100
101 101 def test_empty_notebook(self):
102 102 nb = new_notebook()
103 103 self.assertEqual(nb.worksheets, [])
104 104 self.assertEqual(nb.metadata, NotebookNode())
105 105 self.assertEqual(nb.nbformat,nbformat)
106 106
107 107 def test_notebook(self):
108 108 worksheets = [new_worksheet(),new_worksheet()]
109 109 metadata = new_metadata(name=u'foo')
110 110 nb = new_notebook(metadata=metadata,worksheets=worksheets)
111 111 self.assertEqual(nb.metadata.name,u'foo')
112 112 self.assertEqual(nb.worksheets,worksheets)
113 113 self.assertEqual(nb.nbformat,nbformat)
114 114
115 115 def test_notebook_name(self):
116 116 worksheets = [new_worksheet(),new_worksheet()]
117 117 nb = new_notebook(name='foo',worksheets=worksheets)
118 118 self.assertEqual(nb.metadata.name,u'foo')
119 119 self.assertEqual(nb.worksheets,worksheets)
120 120 self.assertEqual(nb.nbformat,nbformat)
121 121
122 122 class TestMetadata(TestCase):
123 123
124 124 def test_empty_metadata(self):
125 125 md = new_metadata()
126 126 self.assertEqual(u'name' not in md, True)
127 127 self.assertEqual(u'authors' not in md, True)
128 128 self.assertEqual(u'license' not in md, True)
129 129 self.assertEqual(u'saved' not in md, True)
130 130 self.assertEqual(u'modified' not in md, True)
131 131 self.assertEqual(u'gistid' not in md, True)
132 132
133 133 def test_metadata(self):
134 134 authors = [new_author(name='Bart Simpson',email='bsimpson@fox.com')]
135 135 md = new_metadata(name=u'foo',license=u'BSD',created=u'today',
136 136 modified=u'now',gistid=u'21341231',authors=authors)
137 137 self.assertEqual(md.name, u'foo')
138 138 self.assertEqual(md.license, u'BSD')
139 139 self.assertEqual(md.created, u'today')
140 140 self.assertEqual(md.modified, u'now')
141 141 self.assertEqual(md.gistid, u'21341231')
142 142 self.assertEqual(md.authors, authors)
143 143
144 144 class TestOutputs(TestCase):
145 145 def test_binary_png(self):
146 out = new_output(output_png=b'\x89PNG\r\n\x1a\n')
146 out = new_output(output_png=b'\x89PNG\r\n\x1a\n', output_type='display_data')
147 147
148 148 def test_b64b6tes_png(self):
149 out = new_output(output_png=b'iVBORw0KG')
149 out = new_output(output_png=b'iVBORw0KG', output_type='display_data')
150 150
151 151 def test_binary_jpeg(self):
152 out = new_output(output_jpeg=b'\xff\xd8')
152 out = new_output(output_jpeg=b'\xff\xd8', output_type='display_data')
153 153
154 154 def test_b64b6tes_jpeg(self):
155 out = new_output(output_jpeg=b'/9')
155 out = new_output(output_jpeg=b'/9', output_type='display_data')
156 156
157 157
General Comments 0
You need to be logged in to leave comments. Login now