1
1
import importlib
2
2
3
- from traitlets .config import LoggingConfigurable , Config
3
+ from traitlets .config import LoggingConfigurable
4
4
5
5
from traitlets import (
6
6
HasTraits ,
7
7
Dict ,
8
8
Unicode ,
9
9
Bool ,
10
10
Any ,
11
- validate
11
+ Instance ,
12
+ default ,
13
+ observe ,
14
+ validate ,
12
15
)
13
16
17
+ from .config import ExtensionConfigManager
14
18
from .utils import (
15
19
ExtensionMetadataError ,
16
20
ExtensionModuleNotFound ,
@@ -129,6 +133,8 @@ def validate(self):
129
133
self ._get_loader ()
130
134
except Exception :
131
135
return False
136
+ else :
137
+ return True
132
138
133
139
def link (self , serverapp ):
134
140
"""Link the extension to a Jupyter ServerApp object.
@@ -238,35 +244,44 @@ class ExtensionManager(LoggingConfigurable):
238
244
linking, loading, and managing Jupyter Server extensions.
239
245
240
246
Usage:
241
- m = ExtensionManager(jpserver_extensions=extensions )
247
+ m = ExtensionManager(config_manager=... )
242
248
"""
243
- def __init__ (self , config_manager = None , * args , ** kwargs ):
244
- super ().__init__ (* args , ** kwargs )
245
- # The `enabled_extensions` attribute provides a dictionary
246
- # with extension (package) names mapped to their ExtensionPackage interface
247
- # (see above). This manager simplifies the interaction between the
248
- # ServerApp and the extensions being appended.
249
- self ._extensions = {}
250
- # The `_linked_extensions` attribute tracks when each extension
251
- # has been successfully linked to a ServerApp. This helps prevent
252
- # extensions from being re-linked recursively unintentionally if another
253
- # extension attempts to link extensions again.
254
- self ._linked_extensions = {}
255
- self ._config_manager = config_manager
256
- if self ._config_manager :
257
- self .from_config_manager (self ._config_manager )
258
249
259
- @property
260
- def config_manager (self ):
261
- return self ._config_manager
250
+ config_manager = Instance (ExtensionConfigManager , allow_none = True )
251
+
252
+ @default ("config_manager" )
253
+ def _load_default_config_manager (self ):
254
+ config_manager = ExtensionConfigManager ()
255
+ self ._load_config_manager (config_manager )
256
+ return config_manager
257
+
258
+ @observe ("config_manager" )
259
+ def _config_manager_changed (self , change ):
260
+ if change .new :
261
+ self ._load_config_manager (change .new )
262
+
263
+ # The `extensions` attribute provides a dictionary
264
+ # with extension (package) names mapped to their ExtensionPackage interface
265
+ # (see above). This manager simplifies the interaction between the
266
+ # ServerApp and the extensions being appended.
267
+ extensions = Dict (
268
+ help = """
269
+ Dictionary with extension package names as keys
270
+ and ExtensionPackage objects as values.
271
+ """
272
+ )
262
273
263
- @property
264
- def extensions (self ):
265
- """Dictionary with extension package names as keys
266
- and an ExtensionPackage objects as values.
274
+ # The `_linked_extensions` attribute tracks when each extension
275
+ # has been successfully linked to a ServerApp. This helps prevent
276
+ # extensions from being re-linked recursively unintentionally if another
277
+ # extension attempts to link extensions again.
278
+ linked_extensions = Dict (
279
+ help = """
280
+ Dictionary with extension names as keys
281
+
282
+ values are True if the extension is linked, False if not.
267
283
"""
268
- # Sort enabled extensions before
269
- return self ._extensions
284
+ )
270
285
271
286
@property
272
287
def extension_points (self ):
@@ -277,16 +292,14 @@ def extension_points(self):
277
292
for name , point in value .extension_points .items ()
278
293
}
279
294
280
- @property
281
- def linked_extensions (self ):
282
- """Dictionary with extension names as keys; values are
283
- True if the extension is linked, False if not."""
284
- return self ._linked_extensions
285
-
286
295
def from_config_manager (self , config_manager ):
287
296
"""Add extensions found by an ExtensionConfigManager"""
288
- self ._config_manager = config_manager
289
- jpserver_extensions = self ._config_manager .get_jpserver_extensions ()
297
+ # load triggered via config_manager trait observer
298
+ self .config_manager = config_manager
299
+
300
+ def _load_config_manager (self , config_manager ):
301
+ """Actually load our config manager"""
302
+ jpserver_extensions = config_manager .get_jpserver_extensions ()
290
303
self .from_jpserver_extensions (jpserver_extensions )
291
304
292
305
def from_jpserver_extensions (self , jpserver_extensions ):
@@ -300,21 +313,21 @@ def add_extension(self, extension_name, enabled=False):
300
313
"""
301
314
try :
302
315
extpkg = ExtensionPackage (name = extension_name , enabled = enabled )
303
- self ._extensions [extension_name ] = extpkg
316
+ self .extensions [extension_name ] = extpkg
304
317
return True
305
318
# Raise a warning if the extension cannot be loaded.
306
319
except Exception as e :
307
320
self .log .warning (e )
308
321
return False
309
322
310
323
def link_extension (self , name , serverapp ):
311
- linked = self ._linked_extensions .get (name , False )
324
+ linked = self .linked_extensions .get (name , False )
312
325
extension = self .extensions [name ]
313
326
if not linked and extension .enabled :
314
327
try :
315
328
# Link extension and store links
316
329
extension .link_all_points (serverapp )
317
- self ._linked_extensions [name ] = True
330
+ self .linked_extensions [name ] = True
318
331
self .log .info ("{name} | extension was successfully linked." .format (name = name ))
319
332
except Exception as e :
320
333
self .log .warning (e )
0 commit comments