From 897f5f62d5a6e6d74eaa3900bb743cb8a53a8fad Mon Sep 17 00:00:00 2001 From: Min RK Date: Fri, 13 Jul 2018 17:23:19 -0500 Subject: [PATCH] pass requesting handler to spawner allows Spawners to implement logic such as processing GET params to select inputs USE WITH CARE because this gives authors of links the ability to pass parameters to spawn without user knowledge or input. This should only be used for things like selecting from a list of all known-good choices, e.g. a profile list. --- jupyterhub/handlers/base.py | 2 +- jupyterhub/spawner.py | 1 + jupyterhub/user.py | 8 +++++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/jupyterhub/handlers/base.py b/jupyterhub/handlers/base.py index 8e508fce..6f40d6c9 100644 --- a/jupyterhub/handlers/base.py +++ b/jupyterhub/handlers/base.py @@ -602,7 +602,7 @@ class BaseHandler(RequestHandler): self.log.debug("Initiating spawn for %s", user_server_name) - spawn_future = user.spawn(server_name, options) + spawn_future = user.spawn(server_name, options, handler=self) self.log.debug("%i%s concurrent spawns", spawn_pending_count, diff --git a/jupyterhub/spawner.py b/jupyterhub/spawner.py index ff76b66c..c0a7d3a7 100644 --- a/jupyterhub/spawner.py +++ b/jupyterhub/spawner.py @@ -161,6 +161,7 @@ class Spawner(LoggingConfigurable): admin_access = Bool(False) api_token = Unicode() oauth_client_id = Unicode() + handler = Any() will_resume = Bool(False, help="""Whether the Spawner will resume on next start diff --git a/jupyterhub/user.py b/jupyterhub/user.py index f65affc4..95cbb5f8 100644 --- a/jupyterhub/user.py +++ b/jupyterhub/user.py @@ -331,7 +331,7 @@ class User: url_parts.extend(['server/progress']) return url_path_join(*url_parts) - async def spawn(self, server_name='', options=None): + async def spawn(self, server_name='', options=None, handler=None): """Start the user's spawner depending from the value of JupyterHub.allow_named_servers @@ -361,6 +361,9 @@ class User: spawner.server = server = Server(orm_server=orm_server) assert spawner.orm_spawner.server is orm_server + # pass requesting handler to the spawner + # e.g. for processing GET params + spawner.handler = handler # Passing user_options to the spawner spawner.user_options = options or {} # we are starting a new server, make sure it doesn't restore state @@ -484,6 +487,9 @@ class User: # raise original exception spawner._start_pending = False raise e + finally: + # clear reference to handler after start finishes + spawner.handler = None spawner.start_polling() # store state