The Jupyter Notebook web application provides a graphical interface for creating, opening, renaming, and deleting files in a virtual filesystem.
The ContentsManager
class defines an abstract
API for translating these interactions into operations on a particular storage
medium. The default implementation,
FileContentsManager
, uses the local
filesystem of the server for storage and straightforwardly serializes notebooks
into JSON. Users can override these behaviors by supplying custom subclasses
of ContentsManager.
This section describes the interface implemented by ContentsManager subclasses. We refer to this interface as the Contents API.
ContentsManager methods represent virtual filesystem entities as dictionaries, which we refer to as models.
Models may contain the following entries:
Key | Type | Info |
---|---|---|
name | unicode | Basename of the entity. |
path | unicode | Full (API-style) path to the entity. |
type | unicode | The entity type. One of
"notebook" , "file" or
"directory" . |
created | datetime | Creation date of the entity. |
last_modified | datetime | Last modified date of the entity. |
content | variable | The “content” of the entity. (See Below) |
mimetype | unicode or
None |
The mimetype of content ,
if any. (See
Below) |
format | unicode or
None |
The format of content ,
if any. (See
Below) |
Certain model fields vary in structure depending on the type
field of the
model. There are three model types: notebook, file, and directory .
notebook
modelsformat
field is always "json"
.mimetype
field is always None
.content
field contains a
nbformat.notebooknode.NotebookNode
representing the .ipynb file
represented by the model. See the NBFormat documentation for a full
description.file
modelsformat
field is either "text"
or "base64"
.mimetype
field is text/plain
for text-format models and
application/octet-stream
for base64-format models.content
field is always of type unicode
. For text-format
file models, content
simply contains the file’s bytes after decoding
as UTF-8. Non-text (base64
) files are read as bytes, base64 encoded,
and then decoded as UTF-8.directory
modelsformat
field is always "json"
.mimetype
field is always None
.content
field contains a list of content-free
models representing the entities in the directory.Note
In certain circumstances, we don’t need the full content of an entity to
complete a Contents API request. In such cases, we omit the mimetype
,
content
, and format
keys from the model. This most commonly occurs
when listing a directory, in which circumstance we represent files within
the directory as content-less models to avoid having to recursively traverse
and serialize the entire filesystem.
Sample Models
# Notebook Model with Content
{
'content': {
'metadata': {},
'nbformat': 4,
'nbformat_minor': 0,
'cells': [
{
'cell_type': 'markdown',
'metadata': {},
'source': 'Some **Markdown**',
},
],
},
'created': datetime(2015, 7, 25, 19, 50, 19, 19865),
'format': 'json',
'last_modified': datetime(2015, 7, 25, 19, 50, 19, 19865),
'mimetype': None,
'name': 'a.ipynb',
'path': 'foo/a.ipynb',
'type': 'notebook',
'writable': True,
}
# Notebook Model without Content
{
'content': None,
'created': datetime.datetime(2015, 7, 25, 20, 17, 33, 271931),
'format': None,
'last_modified': datetime.datetime(2015, 7, 25, 20, 17, 33, 271931),
'mimetype': None,
'name': 'a.ipynb',
'path': 'foo/a.ipynb',
'type': 'notebook',
'writable': True
}
ContentsManager methods represent the locations of filesystem resources as API-style paths. Such paths are interpreted as relative to the root directory of the notebook server. For compatibility across systems, the following guarantees are made:
unicode
, not bytes
./foo/bar/buzz/
becomes foo/bar/buzz
.""
) represents the root directory.The default ContentsManager is designed for users running the notebook as an
application on a personal computer. It stores notebooks as .ipynb files on the
local filesystem, and it maps files and directories in the Notebook UI to files
and directories on disk. It is possible to override how notebooks are stored
by implementing your own custom subclass of ContentsManager
. For example,
if you deploy the notebook in a context where you don’t trust or don’t have
access to the filesystem of the notebook server, it’s possible to write your
own ContentsManager that stores notebooks and files in a database.
A minimal complete implementation of a custom
ContentsManager
must implement the following
methods:
ContentsManager.get (path[, content, type, ...]) |
Get a file or directory model. |
ContentsManager.save (model, path) |
Save a file or directory model to path. |
ContentsManager.delete_file (path) |
Delete the file or directory at path. |
ContentsManager.rename_file (old_path, new_path) |
Rename a file or directory. |
ContentsManager.file_exists ([path]) |
Does a file exist at the given path? |
ContentsManager.dir_exists (path) |
Does a directory exist at the given path? |
ContentsManager.is_hidden (path) |
Is path a hidden directory or file? |
TODO:
notebook.services.contents.tests
includes several test suites written
against the abstract Contents API. This means that an excellent way to test a
new ContentsManager subclass is to subclass our tests to make them use your
ContentsManager.
Note
PGContents is an example of a complete implementation of a custom
ContentsManager
. It stores notebooks and files in PostgreSQL and encodes
directories as SQL relations. PGContents also provides an example of how to
re-use the notebook’s tests.