/usr/lib/python2.7/dist-packages/notebook/services/sessions/handlers.py is in python-notebook 5.2.2-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | """Tornado handlers for the sessions web service.
Preliminary documentation at https://github.com/ipython/ipython/wiki/IPEP-16%3A-Notebook-multi-directory-dashboard-and-URL-mapping#sessions-api
"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import json
import os
from tornado import gen, web
from ...base.handlers import APIHandler
from jupyter_client.jsonutil import date_default
from notebook.utils import url_path_join
from jupyter_client.kernelspec import NoSuchKernel
class SessionRootHandler(APIHandler):
@web.authenticated
@gen.coroutine
def get(self):
# Return a list of running sessions
sm = self.session_manager
sessions = yield gen.maybe_future(sm.list_sessions())
self.finish(json.dumps(sessions, default=date_default))
@web.authenticated
@gen.coroutine
def post(self):
# Creates a new session
#(unless a session already exists for the named session)
sm = self.session_manager
model = self.get_json_body()
if model is None:
raise web.HTTPError(400, "No JSON data provided")
if 'notebook' in model and 'path' in model['notebook']:
self.log.warning('Sessions API changed, see updated swagger docs')
model['path'] = model['notebook']['path']
model['type'] = 'notebook'
try:
path = model['path']
except KeyError:
raise web.HTTPError(400, "Missing field in JSON data: path")
try:
mtype = model['type']
except KeyError:
raise web.HTTPError(400, "Missing field in JSON data: type")
name = model.get('name', None)
kernel = model.get('kernel', {})
kernel_name = kernel.get('name', None)
kernel_id = kernel.get('id', None)
if not kernel_id and not kernel_name:
self.log.debug("No kernel specified, using default kernel")
kernel_name = None
exists = yield gen.maybe_future(sm.session_exists(path=path))
if exists:
model = yield gen.maybe_future(sm.get_session(path=path))
else:
try:
model = yield gen.maybe_future(
sm.create_session(path=path, kernel_name=kernel_name,
kernel_id=kernel_id, name=name,
type=mtype))
except NoSuchKernel:
msg = ("The '%s' kernel is not available. Please pick another "
"suitable kernel instead, or install that kernel." % kernel_name)
status_msg = '%s not found' % kernel_name
self.log.warning('Kernel not found: %s' % kernel_name)
self.set_status(501)
self.finish(json.dumps(dict(message=msg, short_message=status_msg)))
return
location = url_path_join(self.base_url, 'api', 'sessions', model['id'])
self.set_header('Location', location)
self.set_status(201)
self.finish(json.dumps(model, default=date_default))
class SessionHandler(APIHandler):
@web.authenticated
@gen.coroutine
def get(self, session_id):
# Returns the JSON model for a single session
sm = self.session_manager
model = yield gen.maybe_future(sm.get_session(session_id=session_id))
self.finish(json.dumps(model, default=date_default))
@web.authenticated
@gen.coroutine
def patch(self, session_id):
"""Patch updates sessions:
- path updates session to track renamed paths
- kernel.name starts a new kernel with a given kernelspec
"""
sm = self.session_manager
km = self.kernel_manager
model = self.get_json_body()
if model is None:
raise web.HTTPError(400, "No JSON data provided")
# get the previous session model
before = yield gen.maybe_future(sm.get_session(session_id=session_id))
changes = {}
if 'notebook' in model and 'path' in model['notebook']:
self.log.warning('Sessions API changed, see updated swagger docs')
model['path'] = model['notebook']['path']
model['type'] = 'notebook'
if 'path' in model:
changes['path'] = model['path']
if 'name' in model:
changes['name'] = model['name']
if 'type' in model:
changes['type'] = model['type']
if 'kernel' in model:
# Kernel id takes precedence over name.
if model['kernel'].get('id') is not None:
kernel_id = model['kernel']['id']
if kernel_id not in km:
raise web.HTTPError(400, "No such kernel: %s" % kernel_id)
changes['kernel_id'] = kernel_id
elif model['kernel'].get('name') is not None:
kernel_name = model['kernel']['name']
kernel_id = yield sm.start_kernel_for_session(
session_id, kernel_name=kernel_name, name=before['name'],
path=before['path'], type=before['type'])
changes['kernel_id'] = kernel_id
yield gen.maybe_future(sm.update_session(session_id, **changes))
model = yield gen.maybe_future(sm.get_session(session_id=session_id))
if model['kernel']['id'] != before['kernel']['id']:
# kernel_id changed because we got a new kernel
# shutdown the old one
yield gen.maybe_future(
km.shutdown_kernel(before['kernel']['id'])
)
self.finish(json.dumps(model, default=date_default))
@web.authenticated
@gen.coroutine
def delete(self, session_id):
# Deletes the session with given session_id
sm = self.session_manager
try:
yield gen.maybe_future(sm.delete_session(session_id))
except KeyError:
# the kernel was deleted but the session wasn't!
raise web.HTTPError(410, "Kernel deleted before session")
self.set_status(204)
self.finish()
#-----------------------------------------------------------------------------
# URL to handler mappings
#-----------------------------------------------------------------------------
_session_id_regex = r"(?P<session_id>\w+-\w+-\w+-\w+-\w+)"
default_handlers = [
(r"/api/sessions/%s" % _session_id_regex, SessionHandler),
(r"/api/sessions", SessionRootHandler)
]
|