##// END OF EJS Templates
trust method docstrings
MinRK -
Show More
@@ -1,260 +1,283 b''
1 1 """A base class notebook manager.
2 2
3 3 Authors:
4 4
5 5 * Brian Granger
6 6 * Zach Sailer
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (C) 2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 from fnmatch import fnmatch
21 21 import itertools
22 22 import os
23 23
24 24 from IPython.config.configurable import LoggingConfigurable
25 25 from IPython.nbformat import current, sign
26 26 from IPython.utils.traitlets import Instance, Unicode, List
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # Classes
30 30 #-----------------------------------------------------------------------------
31 31
32 32 class NotebookManager(LoggingConfigurable):
33 33
34 34 filename_ext = Unicode(u'.ipynb')
35 35
36 36 notary = Instance(sign.NotebookNotary)
37 37 def _notary_default(self):
38 38 return sign.NotebookNotary(parent=self)
39 39
40 40 hide_globs = List(Unicode, [u'__pycache__'], config=True, help="""
41 41 Glob patterns to hide in file and directory listings.
42 42 """)
43 43
44 44 # NotebookManager API part 1: methods that must be
45 45 # implemented in subclasses.
46 46
47 47 def path_exists(self, path):
48 48 """Does the API-style path (directory) actually exist?
49 49
50 50 Override this method in subclasses.
51 51
52 52 Parameters
53 53 ----------
54 54 path : string
55 The
55 The path to check
56 56
57 57 Returns
58 58 -------
59 59 exists : bool
60 60 Whether the path does indeed exist.
61 61 """
62 62 raise NotImplementedError
63 63
64 64 def is_hidden(self, path):
65 65 """Does the API style path correspond to a hidden directory or file?
66 66
67 67 Parameters
68 68 ----------
69 69 path : string
70 70 The path to check. This is an API path (`/` separated,
71 71 relative to base notebook-dir).
72 72
73 73 Returns
74 74 -------
75 75 exists : bool
76 76 Whether the path is hidden.
77 77
78 78 """
79 79 raise NotImplementedError
80 80
81 81 def notebook_exists(self, name, path=''):
82 82 """Returns a True if the notebook exists. Else, returns False.
83 83
84 84 Parameters
85 85 ----------
86 86 name : string
87 87 The name of the notebook you are checking.
88 88 path : string
89 89 The relative path to the notebook (with '/' as separator)
90 90
91 91 Returns
92 92 -------
93 93 bool
94 94 """
95 95 raise NotImplementedError('must be implemented in a subclass')
96 96
97 97 # TODO: Remove this after we create the contents web service and directories are
98 98 # no longer listed by the notebook web service.
99 99 def list_dirs(self, path):
100 100 """List the directory models for a given API style path."""
101 101 raise NotImplementedError('must be implemented in a subclass')
102 102
103 103 # TODO: Remove this after we create the contents web service and directories are
104 104 # no longer listed by the notebook web service.
105 105 def get_dir_model(self, name, path=''):
106 106 """Get the directory model given a directory name and its API style path.
107 107
108 108 The keys in the model should be:
109 109 * name
110 110 * path
111 111 * last_modified
112 112 * created
113 113 * type='directory'
114 114 """
115 115 raise NotImplementedError('must be implemented in a subclass')
116 116
117 117 def list_notebooks(self, path=''):
118 118 """Return a list of notebook dicts without content.
119 119
120 120 This returns a list of dicts, each of the form::
121 121
122 122 dict(notebook_id=notebook,name=name)
123 123
124 124 This list of dicts should be sorted by name::
125 125
126 126 data = sorted(data, key=lambda item: item['name'])
127 127 """
128 128 raise NotImplementedError('must be implemented in a subclass')
129 129
130 130 def get_notebook(self, name, path='', content=True):
131 131 """Get the notebook model with or without content."""
132 132 raise NotImplementedError('must be implemented in a subclass')
133 133
134 134 def save_notebook(self, model, name, path=''):
135 135 """Save the notebook and return the model with no content."""
136 136 raise NotImplementedError('must be implemented in a subclass')
137 137
138 138 def update_notebook(self, model, name, path=''):
139 139 """Update the notebook and return the model with no content."""
140 140 raise NotImplementedError('must be implemented in a subclass')
141 141
142 142 def delete_notebook(self, name, path=''):
143 143 """Delete notebook by name and path."""
144 144 raise NotImplementedError('must be implemented in a subclass')
145 145
146 146 def create_checkpoint(self, name, path=''):
147 147 """Create a checkpoint of the current state of a notebook
148 148
149 149 Returns a checkpoint_id for the new checkpoint.
150 150 """
151 151 raise NotImplementedError("must be implemented in a subclass")
152 152
153 153 def list_checkpoints(self, name, path=''):
154 154 """Return a list of checkpoints for a given notebook"""
155 155 return []
156 156
157 157 def restore_checkpoint(self, checkpoint_id, name, path=''):
158 158 """Restore a notebook from one of its checkpoints"""
159 159 raise NotImplementedError("must be implemented in a subclass")
160 160
161 161 def delete_checkpoint(self, checkpoint_id, name, path=''):
162 162 """delete a checkpoint for a notebook"""
163 163 raise NotImplementedError("must be implemented in a subclass")
164 164
165 165 def info_string(self):
166 166 return "Serving notebooks"
167 167
168 168 # NotebookManager API part 2: methods that have useable default
169 169 # implementations, but can be overridden in subclasses.
170 170
171 171 def increment_filename(self, basename, path=''):
172 172 """Increment a notebook filename without the .ipynb to make it unique.
173 173
174 174 Parameters
175 175 ----------
176 176 basename : unicode
177 177 The name of a notebook without the ``.ipynb`` file extension.
178 178 path : unicode
179 179 The URL path of the notebooks directory
180 180
181 181 Returns
182 182 -------
183 183 name : unicode
184 184 A notebook name (with the .ipynb extension) that starts
185 185 with basename and does not refer to any existing notebook.
186 186 """
187 187 path = path.strip('/')
188 188 for i in itertools.count():
189 189 name = u'{basename}{i}{ext}'.format(basename=basename, i=i,
190 190 ext=self.filename_ext)
191 191 if not self.notebook_exists(name, path):
192 192 break
193 193 return name
194 194
195 195 def create_notebook(self, model=None, path=''):
196 196 """Create a new notebook and return its model with no content."""
197 197 path = path.strip('/')
198 198 if model is None:
199 199 model = {}
200 200 if 'content' not in model:
201 201 metadata = current.new_metadata(name=u'')
202 202 model['content'] = current.new_notebook(metadata=metadata)
203 203 if 'name' not in model:
204 204 model['name'] = self.increment_filename('Untitled', path)
205 205
206 206 model['path'] = path
207 207 model = self.save_notebook(model, model['name'], model['path'])
208 208 return model
209 209
210 210 def copy_notebook(self, from_name, to_name=None, path=''):
211 211 """Copy an existing notebook and return its new model.
212 212
213 213 If to_name not specified, increment `from_name-Copy#.ipynb`.
214 214 """
215 215 path = path.strip('/')
216 216 model = self.get_notebook(from_name, path)
217 217 if not to_name:
218 218 base = os.path.splitext(from_name)[0] + '-Copy'
219 219 to_name = self.increment_filename(base, path)
220 220 model['name'] = to_name
221 221 model = self.save_notebook(model, to_name, path)
222 222 return model
223 223
224 224 def log_info(self):
225 225 self.log.info(self.info_string())
226 226
227 227 def trust_notebook(self, name, path=''):
228 """Check for trusted cells, and sign the notebook.
228 """Explicitly trust a notebook
229 229
230 Called as a part of saving notebooks.
230 Parameters
231 ----------
232 name : string
233 The filename of the notebook
234 path : string
235 The notebook's directory
231 236 """
232 237 model = self.get_notebook(name, path)
233 238 nb = model['content']
234 239 self.log.warn("Trusting notebook %s/%s", path, name)
235 240 self.notary.mark_cells(nb, True)
236 241 self.save_notebook(model, name, path)
237 242
238 243 def check_and_sign(self, nb, name, path=''):
239 244 """Check for trusted cells, and sign the notebook.
240 245
241 246 Called as a part of saving notebooks.
247
248 Parameters
249 ----------
250 nb : dict
251 The notebook structure
252 name : string
253 The filename of the notebook
254 path : string
255 The notebook's directory
242 256 """
243 257 if self.notary.check_cells(nb):
244 258 self.notary.sign(nb)
245 259 else:
246 260 self.log.warn("Saving untrusted notebook %s/%s", path, name)
247 261
248 262 def mark_trusted_cells(self, nb, name, path=''):
249 263 """Mark cells as trusted if the notebook signature matches.
250 264
251 265 Called as a part of loading notebooks.
266
267 Parameters
268 ----------
269 nb : dict
270 The notebook structure
271 name : string
272 The filename of the notebook
273 path : string
274 The notebook's directory
252 275 """
253 276 trusted = self.notary.check_signature(nb)
254 277 if not trusted:
255 278 self.log.warn("Notebook %s/%s is not trusted", path, name)
256 279 self.notary.mark_cells(nb, trusted)
257 280
258 281 def should_list(self, name):
259 282 """Should this file/directory name be displayed in a listing?"""
260 283 return not any(fnmatch(name, glob) for glob in self.hide_globs)
General Comments 0
You need to be logged in to leave comments. Login now