##// END OF EJS Templates
test upload of v2 notebooks
MinRK -
Show More
@@ -1,295 +1,312 b''
1 # coding: utf-8
1 # coding: utf-8
2 """Test the notebooks webservice API."""
2 """Test the notebooks webservice API."""
3
3
4 import io
4 import io
5 import json
5 import json
6 import os
6 import os
7 import shutil
7 import shutil
8 from unicodedata import normalize
8 from unicodedata import normalize
9
9
10 pjoin = os.path.join
10 pjoin = os.path.join
11
11
12 import requests
12 import requests
13
13
14 from IPython.html.utils import url_path_join, url_escape
14 from IPython.html.utils import url_path_join, url_escape
15 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
15 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
16 from IPython.nbformat import current
16 from IPython.nbformat.current import (new_notebook, write, read, new_worksheet,
17 from IPython.nbformat.current import (new_notebook, write, read, new_worksheet,
17 new_heading_cell, to_notebook_json)
18 new_heading_cell, to_notebook_json)
19 from IPython.nbformat import v2
18 from IPython.utils import py3compat
20 from IPython.utils import py3compat
19 from IPython.utils.data import uniq_stable
21 from IPython.utils.data import uniq_stable
20
22
21
23
22 class NBAPI(object):
24 class NBAPI(object):
23 """Wrapper for notebook API calls."""
25 """Wrapper for notebook API calls."""
24 def __init__(self, base_url):
26 def __init__(self, base_url):
25 self.base_url = base_url
27 self.base_url = base_url
26
28
27 def _req(self, verb, path, body=None):
29 def _req(self, verb, path, body=None):
28 response = requests.request(verb,
30 response = requests.request(verb,
29 url_path_join(self.base_url, 'api/notebooks', path),
31 url_path_join(self.base_url, 'api/notebooks', path),
30 data=body,
32 data=body,
31 )
33 )
32 response.raise_for_status()
34 response.raise_for_status()
33 return response
35 return response
34
36
35 def list(self, path='/'):
37 def list(self, path='/'):
36 return self._req('GET', path)
38 return self._req('GET', path)
37
39
38 def read(self, name, path='/'):
40 def read(self, name, path='/'):
39 return self._req('GET', url_path_join(path, name))
41 return self._req('GET', url_path_join(path, name))
40
42
41 def create_untitled(self, path='/'):
43 def create_untitled(self, path='/'):
42 return self._req('POST', path)
44 return self._req('POST', path)
43
45
44 def upload_untitled(self, body, path='/'):
46 def upload_untitled(self, body, path='/'):
45 return self._req('POST', path, body)
47 return self._req('POST', path, body)
46
48
47 def copy_untitled(self, copy_from, path='/'):
49 def copy_untitled(self, copy_from, path='/'):
48 body = json.dumps({'copy_from':copy_from})
50 body = json.dumps({'copy_from':copy_from})
49 return self._req('POST', path, body)
51 return self._req('POST', path, body)
50
52
51 def create(self, name, path='/'):
53 def create(self, name, path='/'):
52 return self._req('PUT', url_path_join(path, name))
54 return self._req('PUT', url_path_join(path, name))
53
55
54 def upload(self, name, body, path='/'):
56 def upload(self, name, body, path='/'):
55 return self._req('PUT', url_path_join(path, name), body)
57 return self._req('PUT', url_path_join(path, name), body)
56
58
57 def copy(self, copy_from, copy_to, path='/'):
59 def copy(self, copy_from, copy_to, path='/'):
58 body = json.dumps({'copy_from':copy_from})
60 body = json.dumps({'copy_from':copy_from})
59 return self._req('PUT', url_path_join(path, copy_to), body)
61 return self._req('PUT', url_path_join(path, copy_to), body)
60
62
61 def save(self, name, body, path='/'):
63 def save(self, name, body, path='/'):
62 return self._req('PUT', url_path_join(path, name), body)
64 return self._req('PUT', url_path_join(path, name), body)
63
65
64 def delete(self, name, path='/'):
66 def delete(self, name, path='/'):
65 return self._req('DELETE', url_path_join(path, name))
67 return self._req('DELETE', url_path_join(path, name))
66
68
67 def rename(self, name, path, new_name):
69 def rename(self, name, path, new_name):
68 body = json.dumps({'name': new_name})
70 body = json.dumps({'name': new_name})
69 return self._req('PATCH', url_path_join(path, name), body)
71 return self._req('PATCH', url_path_join(path, name), body)
70
72
71 def get_checkpoints(self, name, path):
73 def get_checkpoints(self, name, path):
72 return self._req('GET', url_path_join(path, name, 'checkpoints'))
74 return self._req('GET', url_path_join(path, name, 'checkpoints'))
73
75
74 def new_checkpoint(self, name, path):
76 def new_checkpoint(self, name, path):
75 return self._req('POST', url_path_join(path, name, 'checkpoints'))
77 return self._req('POST', url_path_join(path, name, 'checkpoints'))
76
78
77 def restore_checkpoint(self, name, path, checkpoint_id):
79 def restore_checkpoint(self, name, path, checkpoint_id):
78 return self._req('POST', url_path_join(path, name, 'checkpoints', checkpoint_id))
80 return self._req('POST', url_path_join(path, name, 'checkpoints', checkpoint_id))
79
81
80 def delete_checkpoint(self, name, path, checkpoint_id):
82 def delete_checkpoint(self, name, path, checkpoint_id):
81 return self._req('DELETE', url_path_join(path, name, 'checkpoints', checkpoint_id))
83 return self._req('DELETE', url_path_join(path, name, 'checkpoints', checkpoint_id))
82
84
83 class APITest(NotebookTestBase):
85 class APITest(NotebookTestBase):
84 """Test the kernels web service API"""
86 """Test the kernels web service API"""
85 dirs_nbs = [('', 'inroot'),
87 dirs_nbs = [('', 'inroot'),
86 ('Directory with spaces in', 'inspace'),
88 ('Directory with spaces in', 'inspace'),
87 (u'unicodΓ©', 'innonascii'),
89 (u'unicodΓ©', 'innonascii'),
88 ('foo', 'a'),
90 ('foo', 'a'),
89 ('foo', 'b'),
91 ('foo', 'b'),
90 ('foo', 'name with spaces'),
92 ('foo', 'name with spaces'),
91 ('foo', u'unicodΓ©'),
93 ('foo', u'unicodΓ©'),
92 ('foo/bar', 'baz'),
94 ('foo/bar', 'baz'),
93 (u'Γ₯ b', u'Γ§ d')
95 (u'Γ₯ b', u'Γ§ d')
94 ]
96 ]
95
97
96 dirs = uniq_stable([d for (d,n) in dirs_nbs])
98 dirs = uniq_stable([d for (d,n) in dirs_nbs])
97 del dirs[0] # remove ''
99 del dirs[0] # remove ''
98
100
99 def setUp(self):
101 def setUp(self):
100 nbdir = self.notebook_dir.name
102 nbdir = self.notebook_dir.name
101
103
102 for d in self.dirs:
104 for d in self.dirs:
103 if not os.path.isdir(pjoin(nbdir, d)):
105 if not os.path.isdir(pjoin(nbdir, d)):
104 os.mkdir(pjoin(nbdir, d))
106 os.mkdir(pjoin(nbdir, d))
105
107
106 for d, name in self.dirs_nbs:
108 for d, name in self.dirs_nbs:
107 with io.open(pjoin(nbdir, d, '%s.ipynb' % name), 'w') as f:
109 with io.open(pjoin(nbdir, d, '%s.ipynb' % name), 'w') as f:
108 nb = new_notebook(name=name)
110 nb = new_notebook(name=name)
109 write(nb, f, format='ipynb')
111 write(nb, f, format='ipynb')
110
112
111 self.nb_api = NBAPI(self.base_url())
113 self.nb_api = NBAPI(self.base_url())
112
114
113 def tearDown(self):
115 def tearDown(self):
114 nbdir = self.notebook_dir.name
116 nbdir = self.notebook_dir.name
115
117
116 for dname in ['foo', 'Directory with spaces in', u'unicodΓ©', u'Γ₯ b']:
118 for dname in ['foo', 'Directory with spaces in', u'unicodΓ©', u'Γ₯ b']:
117 shutil.rmtree(pjoin(nbdir, dname), ignore_errors=True)
119 shutil.rmtree(pjoin(nbdir, dname), ignore_errors=True)
118
120
119 if os.path.isfile(pjoin(nbdir, 'inroot.ipynb')):
121 if os.path.isfile(pjoin(nbdir, 'inroot.ipynb')):
120 os.unlink(pjoin(nbdir, 'inroot.ipynb'))
122 os.unlink(pjoin(nbdir, 'inroot.ipynb'))
121
123
122 def test_list_notebooks(self):
124 def test_list_notebooks(self):
123 nbs = self.nb_api.list().json()
125 nbs = self.nb_api.list().json()
124 self.assertEqual(len(nbs), 1)
126 self.assertEqual(len(nbs), 1)
125 self.assertEqual(nbs[0]['name'], 'inroot.ipynb')
127 self.assertEqual(nbs[0]['name'], 'inroot.ipynb')
126
128
127 nbs = self.nb_api.list('/Directory with spaces in/').json()
129 nbs = self.nb_api.list('/Directory with spaces in/').json()
128 self.assertEqual(len(nbs), 1)
130 self.assertEqual(len(nbs), 1)
129 self.assertEqual(nbs[0]['name'], 'inspace.ipynb')
131 self.assertEqual(nbs[0]['name'], 'inspace.ipynb')
130
132
131 nbs = self.nb_api.list(u'/unicodΓ©/').json()
133 nbs = self.nb_api.list(u'/unicodΓ©/').json()
132 self.assertEqual(len(nbs), 1)
134 self.assertEqual(len(nbs), 1)
133 self.assertEqual(nbs[0]['name'], 'innonascii.ipynb')
135 self.assertEqual(nbs[0]['name'], 'innonascii.ipynb')
134 self.assertEqual(nbs[0]['path'], u'unicodΓ©')
136 self.assertEqual(nbs[0]['path'], u'unicodΓ©')
135
137
136 nbs = self.nb_api.list('/foo/bar/').json()
138 nbs = self.nb_api.list('/foo/bar/').json()
137 self.assertEqual(len(nbs), 1)
139 self.assertEqual(len(nbs), 1)
138 self.assertEqual(nbs[0]['name'], 'baz.ipynb')
140 self.assertEqual(nbs[0]['name'], 'baz.ipynb')
139 self.assertEqual(nbs[0]['path'], 'foo/bar')
141 self.assertEqual(nbs[0]['path'], 'foo/bar')
140
142
141 nbs = self.nb_api.list('foo').json()
143 nbs = self.nb_api.list('foo').json()
142 self.assertEqual(len(nbs), 4)
144 self.assertEqual(len(nbs), 4)
143 nbnames = { normalize('NFC', n['name']) for n in nbs }
145 nbnames = { normalize('NFC', n['name']) for n in nbs }
144 expected = [ u'a.ipynb', u'b.ipynb', u'name with spaces.ipynb', u'unicodΓ©.ipynb']
146 expected = [ u'a.ipynb', u'b.ipynb', u'name with spaces.ipynb', u'unicodΓ©.ipynb']
145 expected = { normalize('NFC', name) for name in expected }
147 expected = { normalize('NFC', name) for name in expected }
146 self.assertEqual(nbnames, expected)
148 self.assertEqual(nbnames, expected)
147
149
148 def test_list_nonexistant_dir(self):
150 def test_list_nonexistant_dir(self):
149 with assert_http_error(404):
151 with assert_http_error(404):
150 self.nb_api.list('nonexistant')
152 self.nb_api.list('nonexistant')
151
153
152 def test_get_contents(self):
154 def test_get_contents(self):
153 for d, name in self.dirs_nbs:
155 for d, name in self.dirs_nbs:
154 nb = self.nb_api.read('%s.ipynb' % name, d+'/').json()
156 nb = self.nb_api.read('%s.ipynb' % name, d+'/').json()
155 self.assertEqual(nb['name'], u'%s.ipynb' % name)
157 self.assertEqual(nb['name'], u'%s.ipynb' % name)
156 self.assertIn('content', nb)
158 self.assertIn('content', nb)
157 self.assertIn('metadata', nb['content'])
159 self.assertIn('metadata', nb['content'])
158 self.assertIsInstance(nb['content']['metadata'], dict)
160 self.assertIsInstance(nb['content']['metadata'], dict)
159
161
160 # Name that doesn't exist - should be a 404
162 # Name that doesn't exist - should be a 404
161 with assert_http_error(404):
163 with assert_http_error(404):
162 self.nb_api.read('q.ipynb', 'foo')
164 self.nb_api.read('q.ipynb', 'foo')
163
165
164 def _check_nb_created(self, resp, name, path):
166 def _check_nb_created(self, resp, name, path):
165 self.assertEqual(resp.status_code, 201)
167 self.assertEqual(resp.status_code, 201)
166 location_header = py3compat.str_to_unicode(resp.headers['Location'])
168 location_header = py3compat.str_to_unicode(resp.headers['Location'])
167 self.assertEqual(location_header, url_escape(url_path_join(u'/api/notebooks', path, name)))
169 self.assertEqual(location_header, url_escape(url_path_join(u'/api/notebooks', path, name)))
168 self.assertEqual(resp.json()['name'], name)
170 self.assertEqual(resp.json()['name'], name)
169 assert os.path.isfile(pjoin(self.notebook_dir.name, path, name))
171 assert os.path.isfile(pjoin(self.notebook_dir.name, path, name))
170
172
171 def test_create_untitled(self):
173 def test_create_untitled(self):
172 resp = self.nb_api.create_untitled(path=u'Γ₯ b')
174 resp = self.nb_api.create_untitled(path=u'Γ₯ b')
173 self._check_nb_created(resp, 'Untitled0.ipynb', u'Γ₯ b')
175 self._check_nb_created(resp, 'Untitled0.ipynb', u'Γ₯ b')
174
176
175 # Second time
177 # Second time
176 resp = self.nb_api.create_untitled(path=u'Γ₯ b')
178 resp = self.nb_api.create_untitled(path=u'Γ₯ b')
177 self._check_nb_created(resp, 'Untitled1.ipynb', u'Γ₯ b')
179 self._check_nb_created(resp, 'Untitled1.ipynb', u'Γ₯ b')
178
180
179 # And two directories down
181 # And two directories down
180 resp = self.nb_api.create_untitled(path='foo/bar')
182 resp = self.nb_api.create_untitled(path='foo/bar')
181 self._check_nb_created(resp, 'Untitled0.ipynb', pjoin('foo', 'bar'))
183 self._check_nb_created(resp, 'Untitled0.ipynb', pjoin('foo', 'bar'))
182
184
183 def test_upload_untitled(self):
185 def test_upload_untitled(self):
184 nb = new_notebook(name='Upload test')
186 nb = new_notebook(name='Upload test')
185 nbmodel = {'content': nb}
187 nbmodel = {'content': nb}
186 resp = self.nb_api.upload_untitled(path=u'Γ₯ b',
188 resp = self.nb_api.upload_untitled(path=u'Γ₯ b',
187 body=json.dumps(nbmodel))
189 body=json.dumps(nbmodel))
188 self._check_nb_created(resp, 'Untitled0.ipynb', u'Γ₯ b')
190 self._check_nb_created(resp, 'Untitled0.ipynb', u'Γ₯ b')
189
191
190 def test_upload(self):
192 def test_upload(self):
191 nb = new_notebook(name=u'ignored')
193 nb = new_notebook(name=u'ignored')
192 nbmodel = {'content': nb}
194 nbmodel = {'content': nb}
193 resp = self.nb_api.upload(u'Upload tΓ©st.ipynb', path=u'Γ₯ b',
195 resp = self.nb_api.upload(u'Upload tΓ©st.ipynb', path=u'Γ₯ b',
194 body=json.dumps(nbmodel))
196 body=json.dumps(nbmodel))
195 self._check_nb_created(resp, u'Upload tΓ©st.ipynb', u'Γ₯ b')
197 self._check_nb_created(resp, u'Upload tΓ©st.ipynb', u'Γ₯ b')
196
198
199 def test_upload_v2(self):
200 nb = v2.new_notebook()
201 ws = v2.new_worksheet()
202 nb.worksheets.append(ws)
203 ws.cells.append(v2.new_code_cell(input='print("hi")'))
204 nbmodel = {'content': nb}
205 resp = self.nb_api.upload(u'Upload tΓ©st.ipynb', path=u'Γ₯ b',
206 body=json.dumps(nbmodel))
207 self._check_nb_created(resp, u'Upload tΓ©st.ipynb', u'Γ₯ b')
208 resp = self.nb_api.read(u'Upload tΓ©st.ipynb', u'Γ₯ b')
209 data = resp.json()
210 self.assertEqual(data['content']['nbformat'], current.nbformat)
211 self.assertEqual(data['content']['orig_nbformat'], 2)
212
197 def test_copy_untitled(self):
213 def test_copy_untitled(self):
198 resp = self.nb_api.copy_untitled(u'Γ§ d.ipynb', path=u'Γ₯ b')
214 resp = self.nb_api.copy_untitled(u'Γ§ d.ipynb', path=u'Γ₯ b')
199 self._check_nb_created(resp, u'Γ§ d-Copy0.ipynb', u'Γ₯ b')
215 self._check_nb_created(resp, u'Γ§ d-Copy0.ipynb', u'Γ₯ b')
200
216
201 def test_copy(self):
217 def test_copy(self):
202 resp = self.nb_api.copy(u'Γ§ d.ipynb', u'cΓΈpy.ipynb', path=u'Γ₯ b')
218 resp = self.nb_api.copy(u'Γ§ d.ipynb', u'cΓΈpy.ipynb', path=u'Γ₯ b')
203 self._check_nb_created(resp, u'cΓΈpy.ipynb', u'Γ₯ b')
219 self._check_nb_created(resp, u'cΓΈpy.ipynb', u'Γ₯ b')
204
220
205 def test_delete(self):
221 def test_delete(self):
206 for d, name in self.dirs_nbs:
222 for d, name in self.dirs_nbs:
207 resp = self.nb_api.delete('%s.ipynb' % name, d)
223 resp = self.nb_api.delete('%s.ipynb' % name, d)
208 self.assertEqual(resp.status_code, 204)
224 self.assertEqual(resp.status_code, 204)
209
225
210 for d in self.dirs + ['/']:
226 for d in self.dirs + ['/']:
211 nbs = self.nb_api.list(d).json()
227 nbs = self.nb_api.list(d).json()
212 self.assertEqual(len(nbs), 0)
228 self.assertEqual(len(nbs), 0)
213
229
214 def test_rename(self):
230 def test_rename(self):
215 resp = self.nb_api.rename('a.ipynb', 'foo', 'z.ipynb')
231 resp = self.nb_api.rename('a.ipynb', 'foo', 'z.ipynb')
216 self.assertEqual(resp.headers['Location'].split('/')[-1], 'z.ipynb')
232 self.assertEqual(resp.headers['Location'].split('/')[-1], 'z.ipynb')
217 self.assertEqual(resp.json()['name'], 'z.ipynb')
233 self.assertEqual(resp.json()['name'], 'z.ipynb')
218 assert os.path.isfile(pjoin(self.notebook_dir.name, 'foo', 'z.ipynb'))
234 assert os.path.isfile(pjoin(self.notebook_dir.name, 'foo', 'z.ipynb'))
219
235
220 nbs = self.nb_api.list('foo').json()
236 nbs = self.nb_api.list('foo').json()
221 nbnames = set(n['name'] for n in nbs)
237 nbnames = set(n['name'] for n in nbs)
222 self.assertIn('z.ipynb', nbnames)
238 self.assertIn('z.ipynb', nbnames)
223 self.assertNotIn('a.ipynb', nbnames)
239 self.assertNotIn('a.ipynb', nbnames)
224
240
225 def test_save(self):
241 def test_save(self):
226 resp = self.nb_api.read('a.ipynb', 'foo')
242 resp = self.nb_api.read('a.ipynb', 'foo')
227 nbcontent = json.loads(resp.text)['content']
243 nbcontent = json.loads(resp.text)['content']
228 nb = to_notebook_json(nbcontent)
244 nb = to_notebook_json(nbcontent)
229 ws = new_worksheet()
245 ws = new_worksheet()
230 nb.worksheets = [ws]
246 nb.worksheets = [ws]
231 ws.cells.append(new_heading_cell(u'Created by test Β³'))
247 ws.cells.append(new_heading_cell(u'Created by test Β³'))
232
248
233 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb}
249 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb}
234 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
250 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
235
251
236 nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb')
252 nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb')
237 with io.open(nbfile, 'r', encoding='utf-8') as f:
253 with io.open(nbfile, 'r', encoding='utf-8') as f:
238 newnb = read(f, format='ipynb')
254 newnb = read(f, format='ipynb')
239 self.assertEqual(newnb.worksheets[0].cells[0].source,
255 self.assertEqual(newnb.worksheets[0].cells[0].source,
240 u'Created by test Β³')
256 u'Created by test Β³')
241 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
257 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
242 newnb = to_notebook_json(nbcontent)
258 newnb = to_notebook_json(nbcontent)
243 self.assertEqual(newnb.worksheets[0].cells[0].source,
259 self.assertEqual(newnb.worksheets[0].cells[0].source,
244 u'Created by test Β³')
260 u'Created by test Β³')
245
261
246 # Save and rename
262 # Save and rename
247 nbmodel= {'name': 'a2.ipynb', 'path':'foo/bar', 'content': nb}
263 nbmodel= {'name': 'a2.ipynb', 'path':'foo/bar', 'content': nb}
248 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
264 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
249 saved = resp.json()
265 saved = resp.json()
250 self.assertEqual(saved['name'], 'a2.ipynb')
266 self.assertEqual(saved['name'], 'a2.ipynb')
251 self.assertEqual(saved['path'], 'foo/bar')
267 self.assertEqual(saved['path'], 'foo/bar')
252 assert os.path.isfile(pjoin(self.notebook_dir.name,'foo','bar','a2.ipynb'))
268 assert os.path.isfile(pjoin(self.notebook_dir.name,'foo','bar','a2.ipynb'))
253 assert not os.path.isfile(pjoin(self.notebook_dir.name, 'foo', 'a.ipynb'))
269 assert not os.path.isfile(pjoin(self.notebook_dir.name, 'foo', 'a.ipynb'))
254 with assert_http_error(404):
270 with assert_http_error(404):
255 self.nb_api.read('a.ipynb', 'foo')
271 self.nb_api.read('a.ipynb', 'foo')
256
272
257 def test_checkpoints(self):
273 def test_checkpoints(self):
258 resp = self.nb_api.read('a.ipynb', 'foo')
274 resp = self.nb_api.read('a.ipynb', 'foo')
259 r = self.nb_api.new_checkpoint('a.ipynb', 'foo')
275 r = self.nb_api.new_checkpoint('a.ipynb', 'foo')
260 self.assertEqual(r.status_code, 201)
276 self.assertEqual(r.status_code, 201)
261 cp1 = r.json()
277 cp1 = r.json()
262 self.assertEqual(set(cp1), {'id', 'last_modified'})
278 self.assertEqual(set(cp1), {'id', 'last_modified'})
263 self.assertEqual(r.headers['Location'].split('/')[-1], cp1['id'])
279 self.assertEqual(r.headers['Location'].split('/')[-1], cp1['id'])
264
280
265 # Modify it
281 # Modify it
266 nbcontent = json.loads(resp.text)['content']
282 nbcontent = json.loads(resp.text)['content']
267 nb = to_notebook_json(nbcontent)
283 nb = to_notebook_json(nbcontent)
268 ws = new_worksheet()
284 ws = new_worksheet()
269 nb.worksheets = [ws]
285 nb.worksheets = [ws]
270 hcell = new_heading_cell('Created by test')
286 hcell = new_heading_cell('Created by test')
271 ws.cells.append(hcell)
287 ws.cells.append(hcell)
272 # Save
288 # Save
273 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb}
289 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb}
274 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
290 resp = self.nb_api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
275
291
276 # List checkpoints
292 # List checkpoints
277 cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json()
293 cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json()
278 self.assertEqual(cps, [cp1])
294 self.assertEqual(cps, [cp1])
279
295
280 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
296 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
281 nb = to_notebook_json(nbcontent)
297 nb = to_notebook_json(nbcontent)
282 self.assertEqual(nb.worksheets[0].cells[0].source, 'Created by test')
298 self.assertEqual(nb.worksheets[0].cells[0].source, 'Created by test')
283
299
284 # Restore cp1
300 # Restore cp1
285 r = self.nb_api.restore_checkpoint('a.ipynb', 'foo', cp1['id'])
301 r = self.nb_api.restore_checkpoint('a.ipynb', 'foo', cp1['id'])
286 self.assertEqual(r.status_code, 204)
302 self.assertEqual(r.status_code, 204)
287 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
303 nbcontent = self.nb_api.read('a.ipynb', 'foo').json()['content']
288 nb = to_notebook_json(nbcontent)
304 nb = to_notebook_json(nbcontent)
289 self.assertEqual(nb.worksheets, [])
305 self.assertEqual(nb.worksheets, [])
290
306
291 # Delete cp1
307 # Delete cp1
292 r = self.nb_api.delete_checkpoint('a.ipynb', 'foo', cp1['id'])
308 r = self.nb_api.delete_checkpoint('a.ipynb', 'foo', cp1['id'])
293 self.assertEqual(r.status_code, 204)
309 self.assertEqual(r.status_code, 204)
294 cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json()
310 cps = self.nb_api.get_checkpoints('a.ipynb', 'foo').json()
295 self.assertEqual(cps, [])
311 self.assertEqual(cps, [])
312
General Comments 0
You need to be logged in to leave comments. Login now