##// END OF EJS Templates
Fixes for notebook session manager
Thomas Kluyver -
Show More
@@ -1,202 +1,202 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
27 27 #-----------------------------------------------------------------------------
28 28 # Classes
29 29 #-----------------------------------------------------------------------------
30 30
31 31 class SessionManager(LoggingConfigurable):
32 32
33 33 # Session database initialized below
34 34 _cursor = None
35 35 _connection = None
36 36 _columns = {'session_id', 'name', 'path', 'kernel_id', 'ws_url'}
37 37
38 38 @property
39 39 def cursor(self):
40 40 """Start a cursor and create a database called 'session'"""
41 41 if self._cursor is None:
42 42 self._cursor = self.connection.cursor()
43 43 self._cursor.execute("""CREATE TABLE session
44 44 (session_id, name, path, kernel_id, ws_url)""")
45 45 return self._cursor
46 46
47 47 @property
48 48 def connection(self):
49 49 """Start a database connection"""
50 50 if self._connection is None:
51 51 self._connection = sqlite3.connect(':memory:')
52 52 self._connection.row_factory = self.row_factory
53 53 return self._connection
54 54
55 55 def __del__(self):
56 56 """Close connection once SessionManager closes"""
57 57 self.cursor.close()
58 58
59 59 def session_exists(self, name, path):
60 60 """Check to see if the session for a given notebook exists"""
61 61 self.cursor.execute("SELECT * FROM session WHERE name=? AND path=?", (name, path))
62 62 reply = self.cursor.fetchone()
63 63 if reply is None:
64 64 return False
65 65 else:
66 66 return True
67 67
68 68 def new_session_id(self):
69 69 "Create a uuid for a new session"
70 70 return unicode_type(uuid.uuid4())
71 71
72 72 def create_session(self, name=None, path=None, kernel_id=None, ws_url=None):
73 73 """Creates a session and returns its model"""
74 74 session_id = self.new_session_id()
75 75 return self.save_session(session_id, name=name, path=path, kernel_id=kernel_id, ws_url=ws_url)
76 76
77 77 def save_session(self, session_id, name=None, path=None, kernel_id=None, ws_url=None):
78 78 """Saves the items for the session with the given session_id
79 79
80 80 Given a session_id (and any other of the arguments), this method
81 81 creates a row in the sqlite session database that holds the information
82 82 for a session.
83 83
84 84 Parameters
85 85 ----------
86 86 session_id : str
87 87 uuid for the session; this method must be given a session_id
88 88 name : str
89 89 the .ipynb notebook name that started the session
90 90 path : str
91 91 the path to the named notebook
92 92 kernel_id : str
93 93 a uuid for the kernel associated with this session
94 94 ws_url : str
95 95 the websocket url
96 96
97 97 Returns
98 98 -------
99 99 model : dict
100 100 a dictionary of the session model
101 101 """
102 102 self.cursor.execute("INSERT INTO session VALUES (?,?,?,?,?)",
103 103 (session_id, name, path, kernel_id, ws_url)
104 104 )
105 105 return self.get_session(session_id=session_id)
106 106
107 107 def get_session(self, **kwargs):
108 108 """Returns the model for a particular session.
109 109
110 110 Takes a keyword argument and searches for the value in the session
111 111 database, then returns the rest of the session's info.
112 112
113 113 Parameters
114 114 ----------
115 115 **kwargs : keyword argument
116 116 must be given one of the keywords and values from the session database
117 117 (i.e. session_id, name, path, kernel_id, ws_url)
118 118
119 119 Returns
120 120 -------
121 121 model : dict
122 122 returns a dictionary that includes all the information from the
123 123 session described by the kwarg.
124 124 """
125 125 if not kwargs:
126 126 raise TypeError("must specify a column to query")
127 127
128 128 conditions = []
129 129 for column in kwargs.keys():
130 130 if column not in self._columns:
131 131 raise TypeError("No such column: %r", column)
132 132 conditions.append("%s=?" % column)
133 133
134 134 query = "SELECT * FROM session WHERE %s" % (' AND '.join(conditions))
135 135
136 self.cursor.execute(query, kwargs.values())
136 self.cursor.execute(query, list(kwargs.values()))
137 137 model = self.cursor.fetchone()
138 138 if model is None:
139 139 q = []
140 140 for key, value in kwargs.items():
141 141 q.append("%s=%r" % (key, value))
142 142
143 143 raise web.HTTPError(404, u'Session not found: %s' % (', '.join(q)))
144 144 return model
145 145
146 146 def update_session(self, session_id, **kwargs):
147 147 """Updates the values in the session database.
148 148
149 149 Changes the values of the session with the given session_id
150 150 with the values from the keyword arguments.
151 151
152 152 Parameters
153 153 ----------
154 154 session_id : str
155 155 a uuid that identifies a session in the sqlite3 database
156 156 **kwargs : str
157 157 the key must correspond to a column title in session database,
158 158 and the value replaces the current value in the session
159 159 with session_id.
160 160 """
161 161 self.get_session(session_id=session_id)
162 162
163 163 if not kwargs:
164 164 # no changes
165 165 return
166 166
167 167 sets = []
168 168 for column in kwargs.keys():
169 169 if column not in self._columns:
170 170 raise TypeError("No such column: %r" % column)
171 171 sets.append("%s=?" % column)
172 172 query = "UPDATE session SET %s WHERE session_id=?" % (', '.join(sets))
173 self.cursor.execute(query, kwargs.values() + [session_id])
173 self.cursor.execute(query, list(kwargs.values()) + [session_id])
174 174
175 175 @staticmethod
176 176 def row_factory(cursor, row):
177 177 """Takes sqlite database session row and turns it into a dictionary"""
178 178 row = sqlite3.Row(cursor, row)
179 179 model = {
180 180 'id': row['session_id'],
181 181 'notebook': {
182 182 'name': row['name'],
183 183 'path': row['path']
184 184 },
185 185 'kernel': {
186 186 'id': row['kernel_id'],
187 187 'ws_url': row['ws_url']
188 188 }
189 189 }
190 190 return model
191 191
192 192 def list_sessions(self):
193 193 """Returns a list of dictionaries containing all the information from
194 194 the session database"""
195 195 c = self.cursor.execute("SELECT * FROM session")
196 196 return list(c.fetchall())
197 197
198 198 def delete_session(self, session_id):
199 199 """Deletes the row in the session database with given session_id"""
200 200 # Check that session exists before deleting
201 201 self.get_session(session_id=session_id)
202 202 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