##// END OF EJS Templates
use invoke instead of fabric...
use invoke instead of fabric it's the descendant of the part of fabric we actually use, it doesn't have complex compiled dependencies like fabric, and it works on Python 3.

File last commit:

r18022:7df5d75a
r18351:0ab76370
Show More
sessionmanager.py
211 lines | 7.6 KiB | text/x-python | PythonLexer
MinRK
allow kernel_name to be undefined in requests...
r18022 """A base class session manager."""
Zachary Sailer
manual rebase - add sessions web service
r12985
MinRK
allow kernel_name to be undefined in requests...
r18022 # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
Zachary Sailer
manual rebase - add sessions web service
r12985
import uuid
Zachary Sailer
session manager restructuring...
r13035 import sqlite3
Zachary Sailer
manual rebase - add sessions web service
r12985
from tornado import web
from IPython.config.configurable import LoggingConfigurable
Thomas Kluyver
Replace references to unicode and basestring
r13353 from IPython.utils.py3compat import unicode_type
Thomas Kluyver
Add kernel name to sessions REST API...
r17222 from IPython.utils.traitlets import Instance
Zachary Sailer
manual rebase - add sessions web service
r12985
class SessionManager(LoggingConfigurable):
Thomas Kluyver
Add kernel name to sessions REST API...
r17222
kernel_manager = Instance('IPython.html.services.kernels.kernelmanager.MappingKernelManager')
MinRK
rename notebooks service to contents service...
r17524 contents_manager = Instance('IPython.html.services.contents.manager.ContentsManager', args=())
Zachary Sailer
manual rebase - add sessions web service
r12985
Zachary Sailer
session manager restructuring...
r13035 # Session database initialized below
_cursor = None
_connection = None
MinRK
remove websocket url...
r15400 _columns = {'session_id', 'name', 'path', 'kernel_id'}
Zachary Sailer
manual rebase - add sessions web service
r12985
Zachary Sailer
session manager restructuring...
r13035 @property
def cursor(self):
"""Start a cursor and create a database called 'session'"""
if self._cursor is None:
self._cursor = self.connection.cursor()
self._cursor.execute("""CREATE TABLE session
MinRK
remove websocket url...
r15400 (session_id, name, path, kernel_id)""")
Zachary Sailer
session manager restructuring...
r13035 return self._cursor
@property
def connection(self):
"""Start a database connection"""
if self._connection is None:
self._connection = sqlite3.connect(':memory:')
Thomas Kluyver
Fix 404 error when accessing nonexistant session
r17775 self._connection.row_factory = sqlite3.Row
Zachary Sailer
session manager restructuring...
r13035 return self._connection
def __del__(self):
"""Close connection once SessionManager closes"""
self.cursor.close()
def session_exists(self, name, path):
MinRK
review pass on Sessions API
r13101 """Check to see if the session for a given notebook exists"""
self.cursor.execute("SELECT * FROM session WHERE name=? AND path=?", (name, path))
Zachary Sailer
session manager restructuring...
r13035 reply = self.cursor.fetchone()
if reply is None:
return False
Zachary Sailer
manual rebase - add sessions web service
r12985 else:
Zachary Sailer
session manager restructuring...
r13035 return True
MinRK
review pass on Sessions API
r13101 def new_session_id(self):
Zachary Sailer
session manager restructuring...
r13035 "Create a uuid for a new session"
Thomas Kluyver
Replace references to unicode and basestring
r13353 return unicode_type(uuid.uuid4())
Zachary Sailer
session manager restructuring...
r13035
MinRK
allow kernel_name to be undefined in requests...
r18022 def create_session(self, name=None, path=None, kernel_name=None):
Zachary Sailer
changes after session manager code review
r13057 """Creates a session and returns its model"""
MinRK
review pass on Sessions API
r13101 session_id = self.new_session_id()
Thomas Kluyver
Add kernel name to sessions REST API...
r17222 # allow nbm to specify kernels cwd
MinRK
rename notebooks service to contents service...
r17524 kernel_path = self.contents_manager.get_kernel_path(name=name, path=path)
Thomas Kluyver
Add kernel name to sessions REST API...
r17222 kernel_id = self.kernel_manager.start_kernel(path=kernel_path,
kernel_name=kernel_name)
return self.save_session(session_id, name=name, path=path,
kernel_id=kernel_id)
Zachary Sailer
changes after session manager code review
r13057
MinRK
remove websocket url...
r15400 def save_session(self, session_id, name=None, path=None, kernel_id=None):
Zachary Sailer
changes after session manager code review
r13057 """Saves the items for the session with the given session_id
Given a session_id (and any other of the arguments), this method
Zachary Sailer
session manager restructuring...
r13035 creates a row in the sqlite session database that holds the information
for a session.
Zachary Sailer
manual rebase - add sessions web service
r12985
Zachary Sailer
session manager restructuring...
r13035 Parameters
----------
session_id : str
uuid for the session; this method must be given a session_id
name : str
the .ipynb notebook name that started the session
path : str
the path to the named notebook
Zachary Sailer
changes after session manager code review
r13057 kernel_id : str
Zachary Sailer
session manager restructuring...
r13035 a uuid for the kernel associated with this session
MinRK
remove websocket url...
r15400
Zachary Sailer
changes after session manager code review
r13057 Returns
-------
model : dict
a dictionary of the session model
Zachary Sailer
session manager restructuring...
r13035 """
MinRK
remove websocket url...
r15400 self.cursor.execute("INSERT INTO session VALUES (?,?,?,?)",
(session_id, name, path, kernel_id)
MinRK
review pass on Sessions API
r13101 )
return self.get_session(session_id=session_id)
Zachary Sailer
session manager restructuring...
r13035
def get_session(self, **kwargs):
Zachary Sailer
changes after session manager code review
r13057 """Returns the model for a particular session.
Takes a keyword argument and searches for the value in the session
Zachary Sailer
session manager restructuring...
r13035 database, then returns the rest of the session's info.
Parameters
----------
**kwargs : keyword argument
must be given one of the keywords and values from the session database
MinRK
remove websocket url...
r15400 (i.e. session_id, name, path, kernel_id)
Zachary Sailer
session manager restructuring...
r13035
Returns
-------
model : dict
returns a dictionary that includes all the information from the
session described by the kwarg.
"""
MinRK
review pass on Sessions API
r13101 if not kwargs:
raise TypeError("must specify a column to query")
conditions = []
for column in kwargs.keys():
if column not in self._columns:
raise TypeError("No such column: %r", column)
conditions.append("%s=?" % column)
query = "SELECT * FROM session WHERE %s" % (' AND '.join(conditions))
Thomas Kluyver
Fixes for notebook session manager
r13377 self.cursor.execute(query, list(kwargs.values()))
Thomas Kluyver
Handle sessions where the kernel has been killed
r17773 try:
Thomas Kluyver
Fix 404 error when accessing nonexistant session
r17775 row = self.cursor.fetchone()
Thomas Kluyver
Handle sessions where the kernel has been killed
r17773 except KeyError:
# The kernel is missing, so the session just got deleted.
Thomas Kluyver
Fix 404 error when accessing nonexistant session
r17775 row = None
Thomas Kluyver
Handle sessions where the kernel has been killed
r17773
Thomas Kluyver
Fix 404 error when accessing nonexistant session
r17775 if row is None:
MinRK
review pass on Sessions API
r13101 q = []
for key, value in kwargs.items():
q.append("%s=%r" % (key, value))
raise web.HTTPError(404, u'Session not found: %s' % (', '.join(q)))
Thomas Kluyver
Fix 404 error when accessing nonexistant session
r17775
return self.row_to_model(row)
Zachary Sailer
session manager restructuring...
r13035
def update_session(self, session_id, **kwargs):
Zachary Sailer
changes after session manager code review
r13057 """Updates the values in the session database.
Changes the values of the session with the given session_id
Zachary Sailer
session manager restructuring...
r13035 with the values from the keyword arguments.
Zachary Sailer
manual rebase - add sessions web service
r12985
Zachary Sailer
session manager restructuring...
r13035 Parameters
----------
session_id : str
a uuid that identifies a session in the sqlite3 database
**kwargs : str
the key must correspond to a column title in session database,
and the value replaces the current value in the session
with session_id.
"""
MinRK
review pass on Sessions API
r13101 self.get_session(session_id=session_id)
if not kwargs:
# no changes
return
sets = []
for column in kwargs.keys():
if column not in self._columns:
raise TypeError("No such column: %r" % column)
sets.append("%s=?" % column)
query = "UPDATE session SET %s WHERE session_id=?" % (', '.join(sets))
Thomas Kluyver
Fixes for notebook session manager
r13377 self.cursor.execute(query, list(kwargs.values()) + [session_id])
MinRK
review pass on Sessions API
r13101
Thomas Kluyver
Fix 404 error when accessing nonexistant session
r17775 def row_to_model(self, row):
Zachary Sailer
session manager restructuring...
r13035 """Takes sqlite database session row and turns it into a dictionary"""
Thomas Kluyver
Handle sessions where the kernel has been killed
r17773 if row['kernel_id'] not in self.kernel_manager:
Thomas Kluyver
Correct comment
r17781 # The kernel was killed or died without deleting the session.
Thomas Kluyver
Add tests and fix some issues...
r17782 # We can't use delete_session here because that tries to find
# and shut down the kernel.
self.cursor.execute("DELETE FROM session WHERE session_id=?",
(row['session_id'],))
Thomas Kluyver
Handle sessions where the kernel has been killed
r17773 raise KeyError
MinRK
review pass on Sessions API
r13101 model = {
'id': row['session_id'],
'notebook': {
'name': row['name'],
'path': row['path']
},
Thomas Kluyver
Add kernel name to sessions REST API...
r17222 'kernel': self.kernel_manager.kernel_model(row['kernel_id'])
MinRK
review pass on Sessions API
r13101 }
Zachary Sailer
session manager restructuring...
r13035 return model
MinRK
review pass on Sessions API
r13101
Zachary Sailer
session manager restructuring...
r13035 def list_sessions(self):
"""Returns a list of dictionaries containing all the information from
the session database"""
MinRK
review pass on Sessions API
r13101 c = self.cursor.execute("SELECT * FROM session")
Thomas Kluyver
Handle sessions where the kernel has been killed
r17773 result = []
Thomas Kluyver
Add tests and fix some issues...
r17782 # We need to use fetchall() here, because row_to_model can delete rows,
# which messes up the cursor if we're iterating over rows.
for row in c.fetchall():
Thomas Kluyver
Handle sessions where the kernel has been killed
r17773 try:
Thomas Kluyver
Fix 404 error when accessing nonexistant session
r17775 result.append(self.row_to_model(row))
Thomas Kluyver
Handle sessions where the kernel has been killed
r17773 except KeyError:
pass
return result
Zachary Sailer
session manager restructuring...
r13035
def delete_session(self, session_id):
"""Deletes the row in the session database with given session_id"""
# Check that session exists before deleting
Thomas Kluyver
Add kernel name to sessions REST API...
r17222 session = self.get_session(session_id=session_id)
self.kernel_manager.shutdown_kernel(session['kernel']['id'])
MinRK
review pass on Sessions API
r13101 self.cursor.execute("DELETE FROM session WHERE session_id=?", (session_id,))