##// END OF EJS Templates
Correct comment
Thomas Kluyver -
Show More
@@ -1,222 +1,222 b''
1 """A base class session manager.
1 """A base class session manager.
2
2
3 Authors:
3 Authors:
4
4
5 * Zach Sailer
5 * Zach Sailer
6 """
6 """
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2013 The IPython Development Team
9 # Copyright (C) 2013 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 import uuid
19 import uuid
20 import sqlite3
20 import sqlite3
21
21
22 from tornado import web
22 from tornado import web
23
23
24 from IPython.config.configurable import LoggingConfigurable
24 from IPython.config.configurable import LoggingConfigurable
25 from IPython.utils.py3compat import unicode_type
25 from IPython.utils.py3compat import unicode_type
26 from IPython.utils.traitlets import Instance
26 from IPython.utils.traitlets import Instance
27
27
28 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
29 # Classes
29 # Classes
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31
31
32 class SessionManager(LoggingConfigurable):
32 class SessionManager(LoggingConfigurable):
33
33
34 kernel_manager = Instance('IPython.html.services.kernels.kernelmanager.MappingKernelManager')
34 kernel_manager = Instance('IPython.html.services.kernels.kernelmanager.MappingKernelManager')
35 contents_manager = Instance('IPython.html.services.contents.manager.ContentsManager', args=())
35 contents_manager = Instance('IPython.html.services.contents.manager.ContentsManager', args=())
36
36
37 # Session database initialized below
37 # Session database initialized below
38 _cursor = None
38 _cursor = None
39 _connection = None
39 _connection = None
40 _columns = {'session_id', 'name', 'path', 'kernel_id'}
40 _columns = {'session_id', 'name', 'path', 'kernel_id'}
41
41
42 @property
42 @property
43 def cursor(self):
43 def cursor(self):
44 """Start a cursor and create a database called 'session'"""
44 """Start a cursor and create a database called 'session'"""
45 if self._cursor is None:
45 if self._cursor is None:
46 self._cursor = self.connection.cursor()
46 self._cursor = self.connection.cursor()
47 self._cursor.execute("""CREATE TABLE session
47 self._cursor.execute("""CREATE TABLE session
48 (session_id, name, path, kernel_id)""")
48 (session_id, name, path, kernel_id)""")
49 return self._cursor
49 return self._cursor
50
50
51 @property
51 @property
52 def connection(self):
52 def connection(self):
53 """Start a database connection"""
53 """Start a database connection"""
54 if self._connection is None:
54 if self._connection is None:
55 self._connection = sqlite3.connect(':memory:')
55 self._connection = sqlite3.connect(':memory:')
56 self._connection.row_factory = sqlite3.Row
56 self._connection.row_factory = sqlite3.Row
57 return self._connection
57 return self._connection
58
58
59 def __del__(self):
59 def __del__(self):
60 """Close connection once SessionManager closes"""
60 """Close connection once SessionManager closes"""
61 self.cursor.close()
61 self.cursor.close()
62
62
63 def session_exists(self, name, path):
63 def session_exists(self, name, path):
64 """Check to see if the session for a given notebook exists"""
64 """Check to see if the session for a given notebook exists"""
65 self.cursor.execute("SELECT * FROM session WHERE name=? AND path=?", (name, path))
65 self.cursor.execute("SELECT * FROM session WHERE name=? AND path=?", (name, path))
66 reply = self.cursor.fetchone()
66 reply = self.cursor.fetchone()
67 if reply is None:
67 if reply is None:
68 return False
68 return False
69 else:
69 else:
70 return True
70 return True
71
71
72 def new_session_id(self):
72 def new_session_id(self):
73 "Create a uuid for a new session"
73 "Create a uuid for a new session"
74 return unicode_type(uuid.uuid4())
74 return unicode_type(uuid.uuid4())
75
75
76 def create_session(self, name=None, path=None, kernel_name='python'):
76 def create_session(self, name=None, path=None, kernel_name='python'):
77 """Creates a session and returns its model"""
77 """Creates a session and returns its model"""
78 session_id = self.new_session_id()
78 session_id = self.new_session_id()
79 # allow nbm to specify kernels cwd
79 # allow nbm to specify kernels cwd
80 kernel_path = self.contents_manager.get_kernel_path(name=name, path=path)
80 kernel_path = self.contents_manager.get_kernel_path(name=name, path=path)
81 kernel_id = self.kernel_manager.start_kernel(path=kernel_path,
81 kernel_id = self.kernel_manager.start_kernel(path=kernel_path,
82 kernel_name=kernel_name)
82 kernel_name=kernel_name)
83 return self.save_session(session_id, name=name, path=path,
83 return self.save_session(session_id, name=name, path=path,
84 kernel_id=kernel_id)
84 kernel_id=kernel_id)
85
85
86 def save_session(self, session_id, name=None, path=None, kernel_id=None):
86 def save_session(self, session_id, name=None, path=None, kernel_id=None):
87 """Saves the items for the session with the given session_id
87 """Saves the items for the session with the given session_id
88
88
89 Given a session_id (and any other of the arguments), this method
89 Given a session_id (and any other of the arguments), this method
90 creates a row in the sqlite session database that holds the information
90 creates a row in the sqlite session database that holds the information
91 for a session.
91 for a session.
92
92
93 Parameters
93 Parameters
94 ----------
94 ----------
95 session_id : str
95 session_id : str
96 uuid for the session; this method must be given a session_id
96 uuid for the session; this method must be given a session_id
97 name : str
97 name : str
98 the .ipynb notebook name that started the session
98 the .ipynb notebook name that started the session
99 path : str
99 path : str
100 the path to the named notebook
100 the path to the named notebook
101 kernel_id : str
101 kernel_id : str
102 a uuid for the kernel associated with this session
102 a uuid for the kernel associated with this session
103
103
104 Returns
104 Returns
105 -------
105 -------
106 model : dict
106 model : dict
107 a dictionary of the session model
107 a dictionary of the session model
108 """
108 """
109 self.cursor.execute("INSERT INTO session VALUES (?,?,?,?)",
109 self.cursor.execute("INSERT INTO session VALUES (?,?,?,?)",
110 (session_id, name, path, kernel_id)
110 (session_id, name, path, kernel_id)
111 )
111 )
112 return self.get_session(session_id=session_id)
112 return self.get_session(session_id=session_id)
113
113
114 def get_session(self, **kwargs):
114 def get_session(self, **kwargs):
115 """Returns the model for a particular session.
115 """Returns the model for a particular session.
116
116
117 Takes a keyword argument and searches for the value in the session
117 Takes a keyword argument and searches for the value in the session
118 database, then returns the rest of the session's info.
118 database, then returns the rest of the session's info.
119
119
120 Parameters
120 Parameters
121 ----------
121 ----------
122 **kwargs : keyword argument
122 **kwargs : keyword argument
123 must be given one of the keywords and values from the session database
123 must be given one of the keywords and values from the session database
124 (i.e. session_id, name, path, kernel_id)
124 (i.e. session_id, name, path, kernel_id)
125
125
126 Returns
126 Returns
127 -------
127 -------
128 model : dict
128 model : dict
129 returns a dictionary that includes all the information from the
129 returns a dictionary that includes all the information from the
130 session described by the kwarg.
130 session described by the kwarg.
131 """
131 """
132 if not kwargs:
132 if not kwargs:
133 raise TypeError("must specify a column to query")
133 raise TypeError("must specify a column to query")
134
134
135 conditions = []
135 conditions = []
136 for column in kwargs.keys():
136 for column in kwargs.keys():
137 if column not in self._columns:
137 if column not in self._columns:
138 raise TypeError("No such column: %r", column)
138 raise TypeError("No such column: %r", column)
139 conditions.append("%s=?" % column)
139 conditions.append("%s=?" % column)
140
140
141 query = "SELECT * FROM session WHERE %s" % (' AND '.join(conditions))
141 query = "SELECT * FROM session WHERE %s" % (' AND '.join(conditions))
142
142
143 self.cursor.execute(query, list(kwargs.values()))
143 self.cursor.execute(query, list(kwargs.values()))
144 try:
144 try:
145 row = self.cursor.fetchone()
145 row = self.cursor.fetchone()
146 except KeyError:
146 except KeyError:
147 # The kernel is missing, so the session just got deleted.
147 # The kernel is missing, so the session just got deleted.
148 row = None
148 row = None
149
149
150 if row is None:
150 if row is None:
151 q = []
151 q = []
152 for key, value in kwargs.items():
152 for key, value in kwargs.items():
153 q.append("%s=%r" % (key, value))
153 q.append("%s=%r" % (key, value))
154
154
155 raise web.HTTPError(404, u'Session not found: %s' % (', '.join(q)))
155 raise web.HTTPError(404, u'Session not found: %s' % (', '.join(q)))
156
156
157 return self.row_to_model(row)
157 return self.row_to_model(row)
158
158
159 def update_session(self, session_id, **kwargs):
159 def update_session(self, session_id, **kwargs):
160 """Updates the values in the session database.
160 """Updates the values in the session database.
161
161
162 Changes the values of the session with the given session_id
162 Changes the values of the session with the given session_id
163 with the values from the keyword arguments.
163 with the values from the keyword arguments.
164
164
165 Parameters
165 Parameters
166 ----------
166 ----------
167 session_id : str
167 session_id : str
168 a uuid that identifies a session in the sqlite3 database
168 a uuid that identifies a session in the sqlite3 database
169 **kwargs : str
169 **kwargs : str
170 the key must correspond to a column title in session database,
170 the key must correspond to a column title in session database,
171 and the value replaces the current value in the session
171 and the value replaces the current value in the session
172 with session_id.
172 with session_id.
173 """
173 """
174 self.get_session(session_id=session_id)
174 self.get_session(session_id=session_id)
175
175
176 if not kwargs:
176 if not kwargs:
177 # no changes
177 # no changes
178 return
178 return
179
179
180 sets = []
180 sets = []
181 for column in kwargs.keys():
181 for column in kwargs.keys():
182 if column not in self._columns:
182 if column not in self._columns:
183 raise TypeError("No such column: %r" % column)
183 raise TypeError("No such column: %r" % column)
184 sets.append("%s=?" % column)
184 sets.append("%s=?" % column)
185 query = "UPDATE session SET %s WHERE session_id=?" % (', '.join(sets))
185 query = "UPDATE session SET %s WHERE session_id=?" % (', '.join(sets))
186 self.cursor.execute(query, list(kwargs.values()) + [session_id])
186 self.cursor.execute(query, list(kwargs.values()) + [session_id])
187
187
188 def row_to_model(self, row):
188 def row_to_model(self, row):
189 """Takes sqlite database session row and turns it into a dictionary"""
189 """Takes sqlite database session row and turns it into a dictionary"""
190 if row['kernel_id'] not in self.kernel_manager:
190 if row['kernel_id'] not in self.kernel_manager:
191 # The kernel was killed without deleting the session. Should never occur.
191 # The kernel was killed or died without deleting the session.
192 self.delete_session(row['session_id'])
192 self.delete_session(row['session_id'])
193 raise KeyError
193 raise KeyError
194
194
195 model = {
195 model = {
196 'id': row['session_id'],
196 'id': row['session_id'],
197 'notebook': {
197 'notebook': {
198 'name': row['name'],
198 'name': row['name'],
199 'path': row['path']
199 'path': row['path']
200 },
200 },
201 'kernel': self.kernel_manager.kernel_model(row['kernel_id'])
201 'kernel': self.kernel_manager.kernel_model(row['kernel_id'])
202 }
202 }
203 return model
203 return model
204
204
205 def list_sessions(self):
205 def list_sessions(self):
206 """Returns a list of dictionaries containing all the information from
206 """Returns a list of dictionaries containing all the information from
207 the session database"""
207 the session database"""
208 c = self.cursor.execute("SELECT * FROM session")
208 c = self.cursor.execute("SELECT * FROM session")
209 result = []
209 result = []
210 for row in c:
210 for row in c:
211 try:
211 try:
212 result.append(self.row_to_model(row))
212 result.append(self.row_to_model(row))
213 except KeyError:
213 except KeyError:
214 pass
214 pass
215 return result
215 return result
216
216
217 def delete_session(self, session_id):
217 def delete_session(self, session_id):
218 """Deletes the row in the session database with given session_id"""
218 """Deletes the row in the session database with given session_id"""
219 # Check that session exists before deleting
219 # Check that session exists before deleting
220 session = self.get_session(session_id=session_id)
220 session = self.get_session(session_id=session_id)
221 self.kernel_manager.shutdown_kernel(session['kernel']['id'])
221 self.kernel_manager.shutdown_kernel(session['kernel']['id'])
222 self.cursor.execute("DELETE FROM session WHERE session_id=?", (session_id,))
222 self.cursor.execute("DELETE FROM session WHERE session_id=?", (session_id,))
General Comments 0
You need to be logged in to leave comments. Login now