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 ,
@@ -240,35 +244,44 @@ class ExtensionManager(LoggingConfigurable):
240
244
linking, loading, and managing Jupyter Server extensions.
241
245
242
246
Usage:
243
- m = ExtensionManager(jpserver_extensions=extensions )
247
+ m = ExtensionManager(config_manager=... )
244
248
"""
245
- def __init__ (self , config_manager = None , * args , ** kwargs ):
246
- super ().__init__ (* args , ** kwargs )
247
- # The `enabled_extensions` attribute provides a dictionary
248
- # with extension (package) names mapped to their ExtensionPackage interface
249
- # (see above). This manager simplifies the interaction between the
250
- # ServerApp and the extensions being appended.
251
- self ._extensions = {}
252
- # The `_linked_extensions` attribute tracks when each extension
253
- # has been successfully linked to a ServerApp. This helps prevent
254
- # extensions from being re-linked recursively unintentionally if another
255
- # extension attempts to link extensions again.
256
- self ._linked_extensions = {}
257
- self ._config_manager = config_manager
258
- if self ._config_manager :
259
- self .from_config_manager (self ._config_manager )
260
249
261
- @property
262
- def config_manager (self ):
263
- 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
+ )
264
273
265
- @property
266
- def extensions (self ):
267
- """Dictionary with extension package names as keys
268
- 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.
269
283
"""
270
- # Sort enabled extensions before
271
- return self ._extensions
284
+ )
272
285
273
286
@property
274
287
def extension_points (self ):
@@ -279,16 +292,14 @@ def extension_points(self):
279
292
for name , point in value .extension_points .items ()
280
293
}
281
294
282
- @property
283
- def linked_extensions (self ):
284
- """Dictionary with extension names as keys; values are
285
- True if the extension is linked, False if not."""
286
- return self ._linked_extensions
287
-
288
295
def from_config_manager (self , config_manager ):
289
296
"""Add extensions found by an ExtensionConfigManager"""
290
- self ._config_manager = config_manager
291
- 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 ()
292
303
self .from_jpserver_extensions (jpserver_extensions )
293
304
294
305
def from_jpserver_extensions (self , jpserver_extensions ):
@@ -302,21 +313,21 @@ def add_extension(self, extension_name, enabled=False):
302
313
"""
303
314
try :
304
315
extpkg = ExtensionPackage (name = extension_name , enabled = enabled )
305
- self ._extensions [extension_name ] = extpkg
316
+ self .extensions [extension_name ] = extpkg
306
317
return True
307
318
# Raise a warning if the extension cannot be loaded.
308
319
except Exception as e :
309
320
self .log .warning (e )
310
321
return False
311
322
312
323
def link_extension (self , name , serverapp ):
313
- linked = self ._linked_extensions .get (name , False )
324
+ linked = self .linked_extensions .get (name , False )
314
325
extension = self .extensions [name ]
315
326
if not linked and extension .enabled :
316
327
try :
317
328
# Link extension and store links
318
329
extension .link_all_points (serverapp )
319
- self ._linked_extensions [name ] = True
330
+ self .linked_extensions [name ] = True
320
331
self .log .info ("{name} | extension was successfully linked." .format (name = name ))
321
332
except Exception as e :
322
333
self .log .warning (e )
0 commit comments