Skip to content

Commit

Permalink
SpawnHandler POST with user form options displays the spawn-pending p…
Browse files Browse the repository at this point in the history
…age just like the GET handler always did
  • Loading branch information
danlester committed Mar 10, 2020
1 parent 1bdc66c commit 3908c6d
Showing 1 changed file with 41 additions and 30 deletions.
71 changes: 41 additions & 30 deletions jupyterhub/handlers/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,7 @@ async def get(self, for_user=None, server_name=''):

spawner = user.spawners[server_name]

# resolve `?next=...`, falling back on the spawn-pending url
# must not be /user/server for named servers,
# which may get handled by the default server if they aren't ready yet

pending_url = url_path_join(
self.hub.base_url, "spawn-pending", user.escaped_name, server_name
)

if self.get_argument('next', None):
# preserve `?next=...` through spawn-pending
pending_url = url_concat(pending_url, {'next': self.get_argument('next')})
pending_url = self._get_pending_url(user, server_name)

# spawner is active, redirect back to get progress, etc.
if spawner.ready:
Expand Down Expand Up @@ -194,24 +184,7 @@ async def get(self, for_user=None, server_name=''):
self.log.debug(
"Triggering spawn with default options for %s", spawner._log_name
)
# Explicit spawn request: clear _spawn_future
# which may have been saved to prevent implicit spawns
# after a failure.
if spawner._spawn_future and spawner._spawn_future.done():
spawner._spawn_future = None
# not running, no form. Trigger spawn and redirect back to /user/:name
f = asyncio.ensure_future(self.spawn_single_user(user, server_name))
done, pending = await asyncio.wait([f], timeout=1)
# If spawn_single_user throws an exception, raise a 500 error
# otherwise it may cause a redirect loop
if f.done() and f.exception():
exc = f.exception()
raise web.HTTPError(
500,
"Error in Authenticator.pre_spawn_start: %s %s"
% (type(exc).__name__, str(exc)),
)
self.redirect(pending_url)
return await self._wrap_spawn_single_user(user, server_name, spawner, pending_url)

@web.authenticated
async def post(self, for_user=None, server_name=''):
Expand Down Expand Up @@ -241,8 +214,12 @@ async def post(self, for_user=None, server_name=''):
for key, byte_list in self.request.files.items():
form_options["%s_file" % key] = byte_list
try:
self.log.debug(
"Triggering spawn with supplied form options for %s", spawner._log_name
)
options = await maybe_future(spawner.options_from_form(form_options))
await self.spawn_single_user(user, server_name=server_name, options=options)
pending_url = self._get_pending_url(user, server_name)
return await self._wrap_spawn_single_user(user, server_name, spawner, pending_url, options)
except Exception as e:
self.log.error(
"Failed to spawn single-user server with form", exc_info=True
Expand All @@ -263,6 +240,40 @@ async def post(self, for_user=None, server_name=''):
)
self.redirect(next_url)

def _get_pending_url(self, user, server_name):
# resolve `?next=...`, falling back on the spawn-pending url
# must not be /user/server for named servers,
# which may get handled by the default server if they aren't ready yet

pending_url = url_path_join(
self.hub.base_url, "spawn-pending", user.escaped_name, server_name
)

if self.get_argument('next', None):
# preserve `?next=...` through spawn-pending
pending_url = url_concat(pending_url, {'next': self.get_argument('next')})

return pending_url

async def _wrap_spawn_single_user(self, user, server_name, spawner, pending_url, options=None):
# Explicit spawn request: clear _spawn_future
# which may have been saved to prevent implicit spawns
# after a failure.
if spawner._spawn_future and spawner._spawn_future.done():
spawner._spawn_future = None
# not running, no form. Trigger spawn and redirect back to /user/:name
f = asyncio.ensure_future(self.spawn_single_user(user, server_name, options=options))
done, pending = await asyncio.wait([f], timeout=1)
# If spawn_single_user throws an exception, raise a 500 error
# otherwise it may cause a redirect loop
if f.done() and f.exception():
exc = f.exception()
raise web.HTTPError(
500,
"Error in Authenticator.pre_spawn_start: %s %s"
% (type(exc).__name__, str(exc)),
)
return self.redirect(pending_url)

class SpawnPendingHandler(BaseHandler):
"""Handle /hub/spawn-pending/:user/:server
Expand Down

0 comments on commit 3908c6d

Please sign in to comment.