Skip to content
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

Allow subclasses to override default service handlers #84

Merged
merged 8 commits into from
Sep 12, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 64 additions & 21 deletions jupyter_server/serverapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,26 @@
jupyter server password # enter a password to protect the server
"""

JUPYTER_SERVICE_HANDLERS = dict(
auth=None,
api=['jupyter_server.services.api.handlers'],
config=['jupyter_server.services.config.handlers'],
contents=['jupyter_server.services.contents.handlers'],
edit=['jupyter_server.edit.handlers'],
files=['jupyter_server.files.handlers'],
kernels=['jupyter_server.services.kernels.handlers'],
kernelspecs=[
'jupyter_server.kernelspecs.handlers',
'jupyter_server.services.kernelspecs.handlers'],
nbconvert=[
'jupyter_server.nbconvert.handlers',
'jupyter_server.services.nbconvert.handlers'],
security=['jupyter_server.services.security.handlers'],
sessions=['jupyter_server.services.sessions.handlers'],
shutdown=['jupyter_server.services.shutdown'],
view=['jupyter_server.view.handlers']
)

#-----------------------------------------------------------------------------
# Helper functions
#-----------------------------------------------------------------------------
Expand All @@ -146,7 +166,7 @@ def load_handlers(name):

class ServerWebApplication(web.Application):

def __init__(self, jupyter_app, kernel_manager, contents_manager,
def __init__(self, jupyter_app, default_services, kernel_manager, contents_manager,
session_manager, kernel_spec_manager,
config_manager, extra_services, log,
base_url, default_url, settings_overrides, jinja_env_options):
Expand All @@ -157,7 +177,7 @@ def __init__(self, jupyter_app, kernel_manager, contents_manager,
session_manager, kernel_spec_manager, config_manager,
extra_services, log, base_url,
default_url, settings_overrides, jinja_env_options)
handlers = self.init_handlers(settings)
handlers = self.init_handlers(default_services, settings)

super(ServerWebApplication, self).__init__(handlers, **settings)

Expand Down Expand Up @@ -271,30 +291,34 @@ def init_settings(self, jupyter_app, kernel_manager, contents_manager,
settings.update(settings_overrides)
return settings

def init_handlers(self, settings):
def init_handlers(self, default_services, settings):
"""Load the (URL pattern, handler) tuples for each component."""

# Order matters. The first handler to match the URL will handle the request.
handlers = []
# load extra services specified by users before default handlers
for service in settings['extra_services']:
handlers.extend(load_handlers(service))
handlers.extend([(r"/login", settings['login_handler_class'])])
handlers.extend([(r"/logout", settings['logout_handler_class'])])
handlers.extend(load_handlers('jupyter_server.files.handlers'))
handlers.extend(load_handlers('jupyter_server.view.handlers'))
handlers.extend(load_handlers('jupyter_server.nbconvert.handlers'))
handlers.extend(load_handlers('jupyter_server.kernelspecs.handlers'))
handlers.extend(load_handlers('jupyter_server.edit.handlers'))
handlers.extend(load_handlers('jupyter_server.services.api.handlers'))
handlers.extend(load_handlers('jupyter_server.services.config.handlers'))
handlers.extend(load_handlers('jupyter_server.services.kernels.handlers'))
handlers.extend(load_handlers('jupyter_server.services.contents.handlers'))
handlers.extend(load_handlers('jupyter_server.services.sessions.handlers'))
handlers.extend(load_handlers('jupyter_server.services.nbconvert.handlers'))
handlers.extend(load_handlers('jupyter_server.services.kernelspecs.handlers'))
handlers.extend(load_handlers('jupyter_server.services.security.handlers'))
handlers.extend(load_handlers('jupyter_server.services.shutdown'))

# Add auth services.
if 'auth' in default_services:
handlers.extend([(r"/login", settings['login_handler_class'])])
handlers.extend([(r"/logout", settings['logout_handler_class'])])

# Load default services. Raise exception if service not
# found in JUPYTER_SERVICE_HANLDERS.
for service in default_services:
if service in JUPYTER_SERVICE_HANDLERS:
locations = JUPYTER_SERVICE_HANDLERS[service]
if locations is not None:
for loc in locations:
handlers.extend(load_handlers(loc))
else:
raise Exception("{} is not recognized as a jupyter_server "
"service. If this is a custom service, "
"try adding it to the "
"`extra_services` list.".format(service))

# Add extra handlers from contents manager.
handlers.extend(settings['contents_manager'].get_extra_handlers())

handlers.append(
Expand Down Expand Up @@ -546,6 +570,25 @@ class ServerApp(JupyterApp):
password=(JupyterPasswordApp, JupyterPasswordApp.description.splitlines()[0]),
)

# A list of services whose handlers will be exposed.
# Subclasses can override this list to
# expose a subset of these handlers.
default_services = (
'api',
'auth',
'config',
Zsailer marked this conversation as resolved.
Show resolved Hide resolved
'contents',
'edit',
'files',
'kernels',
'kernelspecs',
'nbconvert',
'security',
'sessions',
'shutdown',
'view'
)

_log_formatter_cls = LogFormatter

@default('log_level')
Expand Down Expand Up @@ -1220,7 +1263,7 @@ def init_webapp(self):
sys.exit(1)

self.web_app = ServerWebApplication(
self, self.kernel_manager, self.contents_manager,
self, self.default_services, self.kernel_manager, self.contents_manager,
self.session_manager, self.kernel_spec_manager,
self.config_manager, self.extra_services,
self.log, self.base_url, self.default_url, self.tornado_settings,
Expand Down