diff --git a/IPython/html/services/contents/handlers.py b/IPython/html/services/contents/handlers.py
index ea629c9..1e8bd33 100644
--- a/IPython/html/services/contents/handlers.py
+++ b/IPython/html/services/contents/handlers.py
@@ -117,13 +117,19 @@ class ContentsHandler(IPythonHandler):
format = self.get_query_argument('format', default=None)
if format not in {None, 'text', 'base64'}:
raise web.HTTPError(400, u'Format %r is invalid' % format)
-
- model = yield gen.maybe_future(self.contents_manager.get(path=path, type=type, format=format))
- if model['type'] == 'directory':
+ content = self.get_query_argument('content', default='1')
+ if content not in {'0', '1'}:
+ raise web.HTTPError(400, u'Content %r is invalid' % content)
+ content = int(content)
+
+ model = yield gen.maybe_future(self.contents_manager.get(
+ path=path, type=type, format=format, content=content,
+ ))
+ if model['type'] == 'directory' and content:
# group listing by type, then by name (case-insensitive)
# FIXME: sorting should be done in the frontends
model['content'].sort(key=sort_key)
- validate_model(model, expect_content=True)
+ validate_model(model, expect_content=content)
self._finish_model(model, location=False)
@web.authenticated
diff --git a/IPython/html/services/contents/tests/test_contents_api.py b/IPython/html/services/contents/tests/test_contents_api.py
index db46cb6..34e82cc 100644
--- a/IPython/html/services/contents/tests/test_contents_api.py
+++ b/IPython/html/services/contents/tests/test_contents_api.py
@@ -51,12 +51,14 @@ class API(object):
def list(self, path='/'):
return self._req('GET', path)
- def read(self, path, type=None, format=None):
+ def read(self, path, type=None, format=None, content=None):
params = {}
if type is not None:
params['type'] = type
if format is not None:
params['format'] = format
+ if content == False:
+ params['content'] = '0'
return self._req('GET', path, params=params)
def create_untitled(self, path='/', ext='.ipynb'):
@@ -243,6 +245,14 @@ class APITest(NotebookTestBase):
dir_names = {normalize('NFC', d['name']) for d in dirs}
self.assertEqual(dir_names, self.top_level_dirs) # Excluding hidden dirs
+ def test_get_dir_no_content(self):
+ for d in self.dirs:
+ model = self.api.read(d, content=False).json()
+ self.assertEqual(model['path'], d)
+ self.assertEqual(model['type'], 'directory')
+ self.assertIn('content', model)
+ self.assertEqual(model['content'], None)
+
def test_list_nonexistant_dir(self):
with assert_http_error(404):
self.api.list('nonexistant')
@@ -256,10 +266,19 @@ class APITest(NotebookTestBase):
self.assertEqual(nb['type'], 'notebook')
self.assertIn('content', nb)
self.assertEqual(nb['format'], 'json')
- self.assertIn('content', nb)
self.assertIn('metadata', nb['content'])
self.assertIsInstance(nb['content']['metadata'], dict)
+ def test_get_nb_no_content(self):
+ for d, name in self.dirs_nbs:
+ path = url_path_join(d, name + '.ipynb')
+ nb = self.api.read(path, content=False).json()
+ self.assertEqual(nb['name'], u'%s.ipynb' % name)
+ self.assertEqual(nb['path'], path)
+ self.assertEqual(nb['type'], 'notebook')
+ self.assertIn('content', nb)
+ self.assertEqual(nb['content'], None)
+
def test_get_contents_no_such_file(self):
# Name that doesn't exist - should be a 404
with assert_http_error(404):
diff --git a/IPython/html/static/services/contents.js b/IPython/html/static/services/contents.js
index 035e2ee..263c052 100644
--- a/IPython/html/static/services/contents.js
+++ b/IPython/html/static/services/contents.js
@@ -72,13 +72,12 @@ define(function(require) {
/**
* Get a file.
*
- * Calls success with file JSON model, or error with error.
- *
* @method get
* @param {String} path
* @param {Object} options
* type : 'notebook', 'file', or 'directory'
* format: 'text' or 'base64'; only relevant for type: 'file'
+ * content: true or false; // whether to include the content
*/
Contents.prototype.get = function (path, options) {
/**
@@ -94,6 +93,7 @@ define(function(require) {
var params = {};
if (options.type) { params.type = options.type; }
if (options.format) { params.format = options.format; }
+ if (options.content === false) { params.content = '0'; }
return utils.promising_ajax(url + '?' + $.param(params), settings);
};