##// END OF EJS Templates
Add type parameter for contents GET requests
Thomas Kluyver -
Show More
@@ -255,13 +255,18 b' class FileContentsManager(ContentsManager):'
255 self.validate_notebook_model(model)
255 self.validate_notebook_model(model)
256 return model
256 return model
257
257
258 def get_model(self, path, content=True):
258 def get_model(self, path, content=True, type_=None):
259 """ Takes a path for an entity and returns its model
259 """ Takes a path for an entity and returns its model
260
260
261 Parameters
261 Parameters
262 ----------
262 ----------
263 path : str
263 path : str
264 the API path that describes the relative path for the target
264 the API path that describes the relative path for the target
265 content : bool
266 Whether to include the contents in the reply
267 type_ : str, optional
268 The requested type - 'file', 'notebook', or 'directory'.
269 Will raise HTTPError 406 if the content doesn't match.
265
270
266 Returns
271 Returns
267 -------
272 -------
@@ -276,10 +281,16 b' class FileContentsManager(ContentsManager):'
276
281
277 os_path = self._get_os_path(path)
282 os_path = self._get_os_path(path)
278 if os.path.isdir(os_path):
283 if os.path.isdir(os_path):
284 if type_ not in (None, 'directory'):
285 raise web.HTTPError(400,
286 u'%s is a directory, not a %s' % (path, type_))
279 model = self._dir_model(path, content=content)
287 model = self._dir_model(path, content=content)
280 elif path.endswith('.ipynb'):
288 elif type_ == 'notebook' or (type_ is None and path.endswith('.ipynb')):
281 model = self._notebook_model(path, content=content)
289 model = self._notebook_model(path, content=content)
282 else:
290 else:
291 if type_ == 'directory':
292 raise web.HTTPError(400,
293 u'%s is not a directory')
283 model = self._file_model(path, content=content)
294 model = self._file_model(path, content=content)
284 return model
295 return model
285
296
@@ -58,7 +58,11 b' class ContentsHandler(IPythonHandler):'
58 of the files and directories it contains.
58 of the files and directories it contains.
59 """
59 """
60 path = path or ''
60 path = path or ''
61 model = self.contents_manager.get_model(path=path)
61 type_ = self.get_query_argument('type', default=None)
62 if type_ not in {None, 'directory', 'file', 'notebook'}:
63 raise web.HTTPError(400, u'Type %r is invalid' % type_)
64
65 model = self.contents_manager.get_model(path=path, type_=type_)
62 if model['type'] == 'directory':
66 if model['type'] == 'directory':
63 # group listing by type, then by name (case-insensitive)
67 # group listing by type, then by name (case-insensitive)
64 # FIXME: sorting should be done in the frontends
68 # FIXME: sorting should be done in the frontends
@@ -135,7 +135,7 b' class ContentsManager(LoggingConfigurable):'
135 """
135 """
136 return self.file_exists(path) or self.dir_exists(path)
136 return self.file_exists(path) or self.dir_exists(path)
137
137
138 def get_model(self, path, content=True):
138 def get_model(self, path, content=True, type_=None):
139 """Get the model of a file or directory with or without content."""
139 """Get the model of a file or directory with or without content."""
140 raise NotImplementedError('must be implemented in a subclass')
140 raise NotImplementedError('must be implemented in a subclass')
141
141
@@ -46,7 +46,9 b' class API(object):'
46 def list(self, path='/'):
46 def list(self, path='/'):
47 return self._req('GET', path)
47 return self._req('GET', path)
48
48
49 def read(self, path):
49 def read(self, path, type_=None):
50 if type_ is not None:
51 path += '?type=' + type_
50 return self._req('GET', path)
52 return self._req('GET', path)
51
53
52 def create_untitled(self, path='/', ext='.ipynb'):
54 def create_untitled(self, path='/', ext='.ipynb'):
@@ -259,6 +261,13 b' class APITest(NotebookTestBase):'
259 with assert_http_error(404):
261 with assert_http_error(404):
260 self.api.read('foo/q.txt')
262 self.api.read('foo/q.txt')
261
263
264 def test_get_bad_type(self):
265 with assert_http_error(400):
266 self.api.read(u'unicodé', type_='file') # this is a directory
267
268 with assert_http_error(400):
269 self.api.read(u'unicodé/innonascii.ipynb', type_='directory')
270
262 def _check_created(self, resp, path, type='notebook'):
271 def _check_created(self, resp, path, type='notebook'):
263 self.assertEqual(resp.status_code, 201)
272 self.assertEqual(resp.status_code, 201)
264 location_header = py3compat.str_to_unicode(resp.headers['Location'])
273 location_header = py3compat.str_to_unicode(resp.headers['Location'])
@@ -159,6 +159,12 b' class TestContentsManager(TestCase):'
159 self.assertEqual(model['name'], name)
159 self.assertEqual(model['name'], name)
160 self.assertEqual(model['path'], path)
160 self.assertEqual(model['path'], path)
161
161
162 nb_as_file = cm.get_model(path, content=True, type_='file')
163 self.assertEqual(nb_as_file['path'], path)
164 self.assertEqual(nb_as_file['type'], 'file')
165 self.assertEqual(nb_as_file['format'], 'text')
166 self.assertNotIsInstance(nb_as_file['content'], dict)
167
162 # Test in sub-directory
168 # Test in sub-directory
163 sub_dir = '/foo/'
169 sub_dir = '/foo/'
164 self.make_dir(cm.root_dir, 'foo')
170 self.make_dir(cm.root_dir, 'foo')
@@ -170,6 +176,14 b' class TestContentsManager(TestCase):'
170 self.assertIn('content', model2)
176 self.assertIn('content', model2)
171 self.assertEqual(model2['name'], 'Untitled0.ipynb')
177 self.assertEqual(model2['name'], 'Untitled0.ipynb')
172 self.assertEqual(model2['path'], '{0}/{1}'.format(sub_dir.strip('/'), name))
178 self.assertEqual(model2['path'], '{0}/{1}'.format(sub_dir.strip('/'), name))
179
180 # Test getting directory model
181 dirmodel = cm.get_model('foo')
182 self.assertEqual(dirmodel['type'], 'directory')
183
184 with self.assertRaises(HTTPError):
185 cm.get_model('foo', type_='file')
186
173
187
174 @dec.skip_win32
188 @dec.skip_win32
175 def test_bad_symlink(self):
189 def test_bad_symlink(self):
General Comments 0
You need to be logged in to leave comments. Login now