You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
7.0 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

# coding: utf-8
"""Utilities for installing server extensions for the notebook"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
from __future__ import print_function
import sys
from jupyter_core.paths import jupyter_config_path
from ._version import __version__
from .nbextensions import (
BaseNBExtensionApp, ToggleNBExtensionApp, _get_config_dir, _read_config_data,
_write_config_data
)
from traitlets.config.manager import BaseJSONConfigManager, recursive_update
# ------------------------------------------------------------------------------
# Public API
# ------------------------------------------------------------------------------
class ArgumentConflict(ValueError):
pass
def enable_server_extension_python(package, user=False, sys_prefix=False):
"""Enable a server extension associated with a Python package."""
data = _read_config_data(user=user, sys_prefix=sys_prefix)
server_extensions = (
data.setdefault("NotebookApp", {})
.setdefault("server_extensions", [])
)
module, server_exts = _get_server_extension_metadata(package)
for server_ext in server_exts:
require = server_ext['require']
if require not in server_extensions:
server_extensions.append(require)
diff = {'NotebookApp': {'server_extensions': server_extensions}}
recursive_update(data, diff)
_write_config_data(data, user=user, sys_prefix=sys_prefix)
def disable_server_extension_python(package, user=False, sys_prefix=False):
"""Disable a server extension associated with a Python package."""
data = _read_config_data(user=user, sys_prefix=sys_prefix)
server_extensions = (
data.setdefault("NotebookApp", {})
.setdefault("server_extensions", [])
)
module, server_exts = _get_server_extension_metadata(package)
for server_ext in server_exts:
require = server_ext['require']
if require in server_extensions:
server_extensions.remove(require)
diff = {'NotebookApp': {'server_extensions': server_extensions}}
recursive_update(data, diff)
_write_config_data(data, user=user, sys_prefix=sys_prefix)
# ----------------------------------------------------------------------
# Applications
# ----------------------------------------------------------------------
class ToggleServerExtensionApp(ToggleNBExtensionApp):
name = "jupyter serverextension enable/disable"
description = "Enable/disable a server extension using frontend configuration files."
def _toggle_server_extension(self, require):
config_dir = _get_config_dir(user=self.user, sys_prefix=self.sys_prefix)
cm = BaseJSONConfigManager(parent=self, config_dir=config_dir)
cfg = cm.get("jupyter_notebook_config")
server_extensions = (
cfg.setdefault("NotebookApp", {})
.setdefault("nbserver_extensions", {})
)
if self._toggle_value:
server_extensions[require] = True
else:
if self._toggle_value is None:
if require not in server_extensions:
print("server extension not installed")
else:
server_extensions[require] = not server_extensions[require]
else:
server_extensions[require] = False
cm.update("jupyter_notebook_config", cfg)
def toggle_server_extension_python(self, package):
m, server_exts = _get_server_extension_metadata(package)
for server_ext in server_exts:
require = server_ext['require']
self._toggle_server_extension(require)
def toggle_server_extension(self, require):
self._toggle_server_extension(require)
def start(self):
if not self.extra_args:
sys.exit('Please specify a server extension/package to enable or disable')
for arg in self.extra_args:
if self.python:
self.toggle_server_extension_python(arg)
else:
self.toggle_server_extension(arg)
class EnableServerExtensionApp(ToggleServerExtensionApp):
name = "jupyter serverextension enable"
description = "Enable a server extension using frontend configuration files."
_toggle_value = True
class DisableServerExtensionApp(ToggleServerExtensionApp):
name = "jupyter serverextension disable"
description = "Disable an serverextension using frontend configuration files."
_toggle_value = False
class ListServerExtensionsApp(BaseNBExtensionApp):
name = "jupyter serverextension list"
version = __version__
description = "List all server extensions known by the configuration system"
def list_server_extensions(self):
GREEN_CHECK = '\033[92m✔\033[0m'
RED_EX = '\033[91m❌\033[0m'
config_dirs = jupyter_config_path()
for config_dir in config_dirs:
self.log.info('config dir: {}'.format(config_dir))
cm = BaseJSONConfigManager(parent=self, config_dir=config_dir)
data = cm.get("jupyter_notebook_config")
server_extensions = (
data.setdefault("NotebookApp", {})
.setdefault("nbserver_extensions", {})
)
for x in server_extensions:
self.log.info(' {1} {0}'.format(x, GREEN_CHECK if server_extensions[x] else RED_EX))
def start(self):
self.list_server_extensions()
_examples = """
jupyter serverextension list # list all configured nbextensions
jupyter serverextension enable --py <packagename> # enable all nbextensions in a Python package
jupyter serverextension disable --py <packagename> # disable all nbextensions in a Python package
"""
class ServerExtensionApp(BaseNBExtensionApp):
name = "jupyter serverextension"
version = __version__
description = "Work with Jupyter server extensions"
examples = _examples
subcommands = dict(
enable=(EnableServerExtensionApp, "Enable an server extension"),
disable=(DisableServerExtensionApp, "Disable an server extension"),
list=(ListServerExtensionsApp, "List server extensions")
)
def start(self):
super(ServerExtensionApp, self).start()
# The above should have called a subcommand and raised NoStart; if we
# get here, it didn't, so we should self.log.info a message.
subcmds = ", ".join(sorted(self.subcommands))
sys.exit("Please supply at least one subcommand: %s" % subcmds)
main = ServerExtensionApp.launch_instance
# ------------------------------------------------------------------------------
# Private API
# ------------------------------------------------------------------------------
def _get_server_extension_metadata(package):
m = __import__(package)
if not hasattr(m, '_jupyter_server_extension_paths'):
raise KeyError('The Python package {} is not a valid server extension'.format(package))
nbexts = m._jupyter_server_extension_paths()
return m, nbexts
if __name__ == '__main__':
main()