-
Notifications
You must be signed in to change notification settings - Fork 5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
surface config.d nbserver_extensions to the NotebookApp config object #4376
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1539,15 +1539,13 @@ def init_components(self): | |
# TODO: this should still check, but now we use bower, not git submodule | ||
pass | ||
|
||
def init_server_extensions(self): | ||
"""Load any extensions specified by config. | ||
def init_server_extension_config(self): | ||
"""Consolidate server extensions specified by all configs. | ||
|
||
Import the module, then call the load_jupyter_server_extension function, | ||
if one exists. | ||
The resulting list is stored on self.nbserver_extensions and updates config object. | ||
|
||
The extension API is experimental, and may change in future releases. | ||
""" | ||
|
||
# TODO: Remove me in notebook 5.0 | ||
for modulename in self.server_extensions: | ||
# Don't override disable state of the extension if it already exist | ||
|
@@ -1566,15 +1564,23 @@ def init_server_extensions(self): | |
manager = ConfigManager(read_config_path=config_path) | ||
section = manager.get(self.config_file_name) | ||
extensions = section.get('NotebookApp', {}).get('nbserver_extensions', {}) | ||
|
||
for modulename, enabled in sorted(extensions.items()): | ||
if modulename not in self.nbserver_extensions: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this inverts priority when config is defined at both conf.d and top-level. What we had before, was:
What we have here is:
This resolves differently when a given config value is defined at both levels. If you'd like to add a test that verifies this (would be super helpful!), try loading config where There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when you say priority do you mean literal priority in terms of the Dict itself or in terms of overriding? I had thought that user settings should override the defaults. If self.nbserver_extensions already has this modulename then we defer to the user's configuration loaded from the app. Otherwise we adhere to what we find in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That seems backwards to me, that means that as long as that library is installed I can never override its values. Specifically in the case I'm imagining
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where I think this gets murky is if a user's config ends up making their notebook servers not launchable by orchestrators like JupyterHub. As an operator I like to know that a deployment will reliably come up and if there are issues they get surfaced so that we can resolve them. In the current state of affairs like the inconsistency that's being addressed in this PR, the lack of config either doesn't surface (a jupyter server extension doesn't hard stop the server if improperly configured) or ends up buried away in the notebook server logs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That feels like a different case in my mind than what is happening in the I would agree that there should be a case for some way to override user configuration available to deployers. But that shouldn’t be the same convention that libraries are using to ensure their extensions are loaded. Consider that if the person were to upgrade a library that autoenabled an extension by default (an extension that had been explicitly disabled by the deployed). The user would then overwrite the configuration placed as part of deployment in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. However I didn’t intend for this to be a change in behaviour so I’ll switch it back to the previous logic even if I disagree with that logic’s appropriateness to the purpose of this mechanism. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for thinking through it. I think it's tricky to say whether conf.d vs top-level is 'user config' vs not. The priority was based on other conf.d-type systems (profile.d, etc.) where the top-level config is loaded first, followed by I'll go ahead and merge this one. |
||
self.config.NotebookApp.nbserver_extensions.update({modulename: enabled}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This makes it very likely that |
||
self.nbserver_extensions.update({modulename: enabled}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 This is the most important change, I think. |
||
|
||
for modulename, enabled in self.nbserver_extensions.items(): | ||
if modulename not in extensions: | ||
# not present in `extensions` means it comes from Python config, | ||
# so we need to add it. | ||
# Otherwise, trust ConfigManager to have loaded it. | ||
extensions[modulename] = enabled | ||
def init_server_extensions(self): | ||
"""Load any extensions specified by config. | ||
|
||
for modulename, enabled in sorted(extensions.items()): | ||
Import the module, then call the load_jupyter_server_extension function, | ||
if one exists. | ||
|
||
The extension API is experimental, and may change in future releases. | ||
""" | ||
|
||
|
||
for modulename, enabled in sorted(self.nbserver_extensions.items()): | ||
if enabled: | ||
try: | ||
mod = importlib.import_module(modulename) | ||
|
@@ -1632,6 +1638,7 @@ def initialize(self, argv=None): | |
if self._dispatching: | ||
return | ||
self.init_configurables() | ||
self.init_server_extension_config() | ||
self.init_components() | ||
self.init_webapp() | ||
self.init_terminals() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wording is much clearer to me. 👍