##// END OF EJS Templates
handle empty metadata in pyout messages more gracefully.
handle empty metadata in pyout messages more gracefully.

File last commit:

r11145:b584d247
r11673:46e19504
Show More
azurenbmanager.py
143 lines | 5.4 KiB | text/x-python | PythonLexer
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 """A notebook manager that uses Azure blob storage.
Authors:
* Brian Granger
"""
#-----------------------------------------------------------------------------
# Copyright (C) 2012 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
import datetime
import azure
from azure.storage import BlobService
from tornado import web
Brian Granger
Renaming BaseNotebookManager->NotebookManager to preserve config.
r8194 from .nbmanager import NotebookManager
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 from IPython.nbformat import current
from IPython.utils.traitlets import Unicode, Instance
MinRK
add timezone info to `last_modified` in notebook managers...
r11145 from IPython.utils import tz
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
#-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------
Brian Granger
Renaming BaseNotebookManager->NotebookManager to preserve config.
r8194 class AzureNotebookManager(NotebookManager):
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180
account_name = Unicode('', config=True, help='Azure storage account name.')
account_key = Unicode('', config=True, help='Azure storage account key.')
container = Unicode('', config=True, help='Container name for notebooks.')
blob_service_host_base = Unicode('.blob.core.windows.net', config=True,
help='The basename for the blob service URL. If running on the preview site this '
'will be .blob.core.azure-preview.com.')
def _blob_service_host_base_changed(self, new):
self._update_service_host_base(new)
blob_service = Instance('azure.storage.BlobService')
def _blob_service_default(self):
return BlobService(account_name=self.account_name, account_key=self.account_key)
def __init__(self, **kwargs):
Brian Granger
Fixing minor things for the Azure backed nb storage.
r8181 super(AzureNotebookManager, self).__init__(**kwargs)
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 self._update_service_host_base(self.blob_service_host_base)
self._create_container()
def _update_service_host_base(self, shb):
azure.BLOB_SERVICE_HOST_BASE = shb
def _create_container(self):
self.blob_service.create_container(self.container)
def load_notebook_names(self):
"""On startup load the notebook ids and names from Azure.
The blob names are the notebook ids and the notebook names are stored
as blob metadata.
"""
self.mapping = {}
blobs = self.blob_service.list_blobs(self.container)
ids = [blob.name for blob in blobs]
for id in ids:
md = self.blob_service.get_blob_metadata(self.container, id)
name = md['x-ms-meta-nbname']
self.mapping[id] = name
def list_notebooks(self):
"""List all notebooks in the container.
This version uses `self.mapping` as the authoritative notebook list.
"""
data = [dict(notebook_id=id,name=name) for id, name in self.mapping.items()]
data = sorted(data, key=lambda item: item['name'])
return data
def read_notebook_object(self, notebook_id):
"""Get the object representation of a notebook by notebook_id."""
if not self.notebook_exists(notebook_id):
raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
try:
s = self.blob_service.get_blob(self.container, notebook_id)
except:
raise web.HTTPError(500, u'Notebook cannot be read.')
try:
# v1 and v2 and json in the .ipynb files.
nb = current.reads(s, u'json')
except:
raise web.HTTPError(500, u'Unreadable JSON notebook.')
# Todo: The last modified should actually be saved in the notebook document.
# We are just using the current datetime until that is implemented.
MinRK
add timezone info to `last_modified` in notebook managers...
r11145 last_modified = tz.utcnow()
Brian Granger
Refactoring notebook managers and adding Azure backed storage....
r8180 return last_modified, nb
def write_notebook_object(self, nb, notebook_id=None):
"""Save an existing notebook object by notebook_id."""
try:
new_name = nb.metadata.name
except AttributeError:
raise web.HTTPError(400, u'Missing notebook name')
if notebook_id is None:
notebook_id = self.new_notebook_id(new_name)
if notebook_id not in self.mapping:
raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
try:
data = current.writes(nb, u'json')
except Exception as e:
raise web.HTTPError(400, u'Unexpected error while saving notebook: %s' % e)
metadata = {'nbname': new_name}
try:
self.blob_service.put_blob(self.container, notebook_id, data, 'BlockBlob', x_ms_meta_name_values=metadata)
except Exception as e:
raise web.HTTPError(400, u'Unexpected error while saving notebook: %s' % e)
self.mapping[notebook_id] = new_name
return notebook_id
def delete_notebook(self, notebook_id):
"""Delete notebook by notebook_id."""
if not self.notebook_exists(notebook_id):
raise web.HTTPError(404, u'Notebook does not exist: %s' % notebook_id)
try:
self.blob_service.delete_blob(self.container, notebook_id)
except Exception as e:
raise web.HTTPError(400, u'Unexpected error while deleting notebook: %s' % e)
else:
self.delete_notebook_id(notebook_id)
Brian Granger
Fixing minor things for the Azure backed nb storage.
r8181
Paul Ivanov
print info string on interrupt, log it on startup
r10019 def info_string(self):
return "Serving notebooks from Azure storage: %s, %s" % (self.account_name, self.container)