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