mbuali's picture
Upload folder using huggingface_hub
d1ceb73 verified
from functools import wraps
from copy import deepcopy
from traitlets import TraitError
from traitlets.config.loader import (
Config,
)
from jupyter_core.application import JupyterApp
from jupyter_server.serverapp import ServerApp
from jupyter_server.extension.application import ExtensionApp
from .traits import NotebookAppTraits
def NBAPP_AND_SVAPP_SHIM_MSG(trait_name): return (
"'{trait_name}' was found in both NotebookApp "
"and ServerApp. This is likely a recent change. "
"This config will only be set in NotebookApp. "
"Please check if you should also config these traits in "
"ServerApp for your purpose.".format(
trait_name=trait_name,
)
)
def NBAPP_TO_SVAPP_SHIM_MSG(trait_name): return (
"'{trait_name}' has moved from NotebookApp to "
"ServerApp. This config will be passed to ServerApp. "
"Be sure to update your config before "
"our next release.".format(
trait_name=trait_name,
)
)
def EXTAPP_AND_NBAPP_AND_SVAPP_SHIM_MSG(trait_name, extapp_name): return (
"'{trait_name}' is found in {extapp_name}, NotebookApp, "
"and ServerApp. This is a recent change. "
"This config will only be set in {extapp_name}. "
"Please check if you should also config these traits in "
"NotebookApp and ServerApp for your purpose.".format(
trait_name=trait_name,
extapp_name=extapp_name
)
)
def EXTAPP_AND_SVAPP_SHIM_MSG(trait_name, extapp_name): return (
"'{trait_name}' is found in both {extapp_name} "
"and ServerApp. This is a recent change. "
"This config will only be set in {extapp_name}. "
"Please check if you should also config these traits in "
"ServerApp for your purpose.".format(
trait_name=trait_name,
extapp_name=extapp_name
)
)
def EXTAPP_AND_NBAPP_SHIM_MSG(trait_name, extapp_name): return (
"'{trait_name}' is found in both {extapp_name} "
"and NotebookApp. This is a recent change. "
"This config will only be set in {extapp_name}. "
"Please check if you should also config these traits in "
"NotebookApp for your purpose.".format(
trait_name=trait_name,
extapp_name=extapp_name
)
)
def NOT_EXTAPP_NBAPP_AND_SVAPP_SHIM_MSG(trait_name, extapp_name): return (
"'{trait_name}' is not found in {extapp_name}, but "
"it was found in both NotebookApp "
"and ServerApp. This is likely a recent change. "
"This config will only be set in ServerApp. "
"Please check if you should also config these traits in "
"NotebookApp for your purpose.".format(
trait_name=trait_name,
extapp_name=extapp_name
)
)
def EXTAPP_TO_SVAPP_SHIM_MSG(trait_name, extapp_name): return (
"'{trait_name}' has moved from {extapp_name} to "
"ServerApp. Be sure to update your config before "
"our next release.".format(
trait_name=trait_name,
extapp_name=extapp_name
)
)
def EXTAPP_TO_NBAPP_SHIM_MSG(trait_name, extapp_name): return (
"'{trait_name}' has moved from {extapp_name} to "
"NotebookApp. Be sure to update your config before "
"our next release.".format(
trait_name=trait_name,
extapp_name=extapp_name
)
)
# A tuple of traits that shouldn't be shimmed or throw any
# warnings of any kind.
IGNORED_TRAITS = ("open_browser", "log_level", "log_format", "default_url", "show_banner")
class NotebookConfigShimMixin:
"""A Mixin class for shimming configuration from
NotebookApp to ServerApp. This class handles warnings, errors,
etc.
This class should be used during a transition period for apps
that are switching from depending on NotebookApp to ServerApp.
After one release cycle, this class can be safely removed
from the inheriting class.
TL;DR
The entry point to shimming is at the `update_config` method.
Once traits are loaded, before updating config across all
configurable objects, this class injects a method to reroute
traits to their *most logical* classes.
This class raises warnings when:
1. a trait has moved.
2. a trait is redundant across classes.
Redundant traits across multiple classes now must be
configured separately, *or* removed from their old
location to avoid this warning.
For a longer description on how individual traits are handled,
read the docstring under `shim_config_from_notebook_to_jupyter_server`.
"""
@wraps(JupyterApp.update_config)
def update_config(self, config):
# Shim traits to handle transition from NotebookApp to ServerApp
shimmed_config = self.shim_config_from_notebook_to_jupyter_server(
config)
super().update_config(shimmed_config)
def shim_config_from_notebook_to_jupyter_server(self, config):
"""Reorganizes a config object to reroute traits to their expected destinations
after the transition from NotebookApp to ServerApp.
A detailed explanation of how traits are handled:
1. If the argument is prefixed with `ServerApp`,
pass this trait to `ServerApp`.
2. If the argument is prefixed with `NotebookApp`,
* If the argument is a trait of `NotebookApp` *and* `ServerApp`:
1. Raise a warning—**for the extension developers**—that
there's redundant traits.
2. Pass trait to `NotebookApp`.
* If the argument is a trait of just `ServerApp` only
(i.e. the trait moved from `NotebookApp` to `ServerApp`):
1. Raise a "this trait has moved" **for the user**.
3. Pass trait to `ServerApp`.
* If the argument is a trait of `NotebookApp` only, pass trait
to `NotebookApp`.
* If the argument is not found in any object, raise a
`"Trait not found."` error.
3. If the argument is prefixed with `ExtensionApp`:
* If the argument is a trait of `ExtensionApp`,
`NotebookApp`, and `ServerApp`,
1. Raise a warning about redundancy.
2. Pass to the ExtensionApp
* If the argument is a trait of `ExtensionApp` and `NotebookApp`,
1. Raise a warning about redundancy.
2. Pass to ExtensionApp.
* If the argument is a trait of `ExtensionApp` and `ServerApp`,
1. Raise a warning about redundancy.
2. Pass to ExtensionApp.
* If the argument is a trait of `ExtensionApp`.
1. Pass to ExtensionApp.
* If the argument is a trait of `NotebookApp` but not `ExtensionApp`,
1. Raise a warning that trait has likely moved to NotebookApp.
2. Pass to NotebookApp
* If the arguent is a trait of `ServerApp` but not `ExtensionApp`,
1. Raise a warning that the trait has likely moved to ServerApp.
2. Pass to ServerApp.
* else
* Raise a TraitError: "trait not found."
"""
extapp_name = self.__class__.__name__
# Pop out the various configurable objects that we need to evaluate.
nbapp_config = config.pop('NotebookApp', {})
svapp_config = config.pop('ServerApp', {})
extapp_config = config.pop(extapp_name, {})
# Created shimmed configs.
# Leave the rest of the config alone.
config_shim = deepcopy(config)
svapp_config_shim = {}
nbapp_config_shim = {}
extapp_config_shim = {}
extapp_traits = (
self.__class__.class_trait_names() +
ExtensionApp.class_trait_names()
)
svapp_traits = ServerApp.class_trait_names()
nbapp_traits = (
NotebookAppTraits.class_trait_names() +
ExtensionApp.class_trait_names()
)
# 1. Handle ServerApp traits.
svapp_config_shim.update(svapp_config)
# 2. Handle NotebookApp traits.
warning_msg = None
for trait_name, trait_value in nbapp_config.items():
in_svapp = trait_name in svapp_traits
in_nbapp = trait_name in nbapp_traits
if trait_name in IGNORED_TRAITS:
# Pass trait through without any warning message.
nbapp_config_shim.update({trait_name: trait_value})
elif in_svapp and in_nbapp:
warning_msg = NBAPP_AND_SVAPP_SHIM_MSG(trait_name)
nbapp_config_shim.update({trait_name: trait_value})
elif in_svapp:
warning_msg = NBAPP_TO_SVAPP_SHIM_MSG(trait_name)
svapp_config_shim.update({trait_name: trait_value})
elif in_nbapp:
nbapp_config_shim.update({trait_name: trait_value})
else:
raise TraitError("Trait, {}, not found.".format(trait_name))
# Raise a warning if it's given.
if warning_msg:
self.log.warning(warning_msg)
# 3. Handle ExtensionApp traits.
warning_msg = None
for trait_name, trait_value in extapp_config.items():
in_extapp = trait_name in extapp_traits
in_svapp = trait_name in svapp_traits
in_nbapp = trait_name in nbapp_traits
if trait_name in IGNORED_TRAITS:
# Pass trait through without any warning message.
extapp_config_shim.update({trait_name: trait_value})
elif all([in_extapp, in_svapp, in_nbapp]):
warning_msg = EXTAPP_AND_NBAPP_AND_SVAPP_SHIM_MSG(
trait_name,
extapp_name
)
extapp_config_shim.update({trait_name: trait_value})
elif in_extapp and in_svapp:
warning_msg = EXTAPP_AND_SVAPP_SHIM_MSG(
trait_name,
extapp_name
)
extapp_config_shim.update({trait_name: trait_value})
elif in_extapp and in_nbapp:
warning_msg = EXTAPP_AND_NBAPP_SHIM_MSG(
trait_name,
extapp_name
)
extapp_config_shim.update({trait_name: trait_value})
elif in_extapp:
extapp_config_shim.update({trait_name: trait_value})
elif in_svapp and in_nbapp:
warning_msg = NOT_EXTAPP_NBAPP_AND_SVAPP_SHIM_MSG(
trait_name,
extapp_name
)
svapp_config_shim.update({trait_name: trait_value})
elif in_svapp:
warning_msg = EXTAPP_TO_SVAPP_SHIM_MSG(
trait_name,
extapp_name
)
svapp_config_shim.update({trait_name: trait_value})
elif in_nbapp:
warning_msg = EXTAPP_TO_NBAPP_SHIM_MSG(
trait_name,
extapp_name
)
nbapp_config_shim.update({trait_name: trait_value})
else:
raise TraitError("Trait, {}, not found.".format(trait_name))
# Raise warning if one is given
if warning_msg:
self.log.warning(warning_msg)
# Build config for shimmed traits.
new_config = Config({
'NotebookApp': nbapp_config_shim,
'ServerApp': svapp_config_shim,
})
if extapp_config_shim:
new_config.update(Config({
self.__class__.__name__: extapp_config_shim
}))
# Update the full config with new values
config_shim.update(new_config)
return config_shim