diff --git a/IPython/html/services/kernels/handlers.py b/IPython/html/services/kernels/handlers.py index 8f959f9..3f11771 100644 --- a/IPython/html/services/kernels/handlers.py +++ b/IPython/html/services/kernels/handlers.py @@ -36,22 +36,27 @@ class MainKernelHandler(IPythonHandler): @web.authenticated def get(self): km = self.kernel_manager - self.finish(jsonapi.dumps(km.list_kernel_ids())) + self.finish(jsonapi.dumps(km.list_kernels())) @web.authenticated def post(self): km = self.kernel_manager nbm = self.notebook_manager - notebook_id = self.get_argument('notebook', default=None) - kernel_id = km.start_kernel(notebook_id, cwd=nbm.notebook_dir) - data = {'ws_url':self.ws_url,'kernel_id':kernel_id} + kernel_id = km.start_kernel(cwd=nbm.notebook_dir) + model = km.kernel_model(kernel_id, self.ws_url) self.set_header('Location', '{0}kernels/{1}'.format(self.base_kernel_url, kernel_id)) - self.finish(jsonapi.dumps(data)) + self.finish(jsonapi.dumps(model)) class KernelHandler(IPythonHandler): - SUPPORTED_METHODS = ('DELETE') + SUPPORTED_METHODS = ('DELETE', 'GET') + + @web.authenticated + def get(self, kernel_id): + km = self.kernel_manager + model = km.kernel_model(kernel_id,self.ws_url) + self.finish(jsonapi.dumps(model)) @web.authenticated def delete(self, kernel_id): @@ -71,9 +76,9 @@ class KernelActionHandler(IPythonHandler): self.set_status(204) if action == 'restart': km.restart_kernel(kernel_id) - data = {'ws_url':self.ws_url, 'kernel_id':kernel_id} + model = km.kernel_model(kernel_id,self.ws_url) self.set_header('Location', '{0}kernels/{1}'.format(self.base_kernel_url, kernel_id)) - self.write(jsonapi.dumps(data)) + self.write(jsonapi.dumps(model)) self.finish() @@ -173,10 +178,10 @@ _kernel_id_regex = r"(?P\w+-\w+-\w+-\w+-\w+)" _kernel_action_regex = r"(?Prestart|interrupt)" default_handlers = [ - (r"/kernels", MainKernelHandler), - (r"/kernels/%s" % _kernel_id_regex, KernelHandler), - (r"/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler), - (r"/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler), - (r"/kernels/%s/shell" % _kernel_id_regex, ShellHandler), - (r"/kernels/%s/stdin" % _kernel_id_regex, StdinHandler) + (r"/api/kernels", MainKernelHandler), + (r"/api/kernels/%s" % _kernel_id_regex, KernelHandler), + (r"/api/kernels/%s/%s" % (_kernel_id_regex, _kernel_action_regex), KernelActionHandler), + (r"/api/kernels/%s/iopub" % _kernel_id_regex, IOPubHandler), + (r"/api/kernels/%s/shell" % _kernel_id_regex, ShellHandler), + (r"/api/kernels/%s/stdin" % _kernel_id_regex, StdinHandler) ] diff --git a/IPython/html/services/kernels/kernelmanager.py b/IPython/html/services/kernels/kernelmanager.py index 93ba04d..a797a98 100644 --- a/IPython/html/services/kernels/kernelmanager.py +++ b/IPython/html/services/kernels/kernelmanager.py @@ -35,56 +35,31 @@ class MappingKernelManager(MultiKernelManager): return "IPython.kernel.ioloop.IOLoopKernelManager" kernel_argv = List(Unicode) - - _notebook_mapping = Dict() + kernels = [] #------------------------------------------------------------------------- # Methods for managing kernels and sessions #------------------------------------------------------------------------- - def kernel_for_notebook(self, notebook_id): - """Return the kernel_id for a notebook_id or None.""" - return self._notebook_mapping.get(notebook_id) - - def set_kernel_for_notebook(self, notebook_id, kernel_id): - """Associate a notebook with a kernel.""" - if notebook_id is not None: - self._notebook_mapping[notebook_id] = kernel_id - - def notebook_for_kernel(self, kernel_id): - """Return the notebook_id for a kernel_id or None.""" - for notebook_id, kid in self._notebook_mapping.iteritems(): - if kernel_id == kid: - return notebook_id - return None - - def delete_mapping_for_kernel(self, kernel_id): - """Remove the kernel/notebook mapping for kernel_id.""" - notebook_id = self.notebook_for_kernel(kernel_id) - if notebook_id is not None: - del self._notebook_mapping[notebook_id] - def _handle_kernel_died(self, kernel_id): """notice that a kernel died""" self.log.warn("Kernel %s died, removing from map.", kernel_id) - self.delete_mapping_for_kernel(kernel_id) self.remove_kernel(kernel_id) - def start_kernel(self, notebook_id=None, **kwargs): - """Start a kernel for a notebook an return its kernel_id. + def start_kernel(self, **kwargs): + """Start a kernel for a session an return its kernel_id. Parameters ---------- - notebook_id : uuid - The uuid of the notebook to associate the new kernel with. If this - is not None, this kernel will be persistent whenever the notebook + session_id : uuid + The uuid of the session to associate the new kernel with. If this + is not None, this kernel will be persistent whenever the session requests a kernel. """ - kernel_id = self.kernel_for_notebook(notebook_id) + kernel_id = None if kernel_id is None: kwargs['extra_arguments'] = self.kernel_argv kernel_id = super(MappingKernelManager, self).start_kernel(**kwargs) - self.set_kernel_for_notebook(notebook_id, kernel_id) self.log.info("Kernel started: %s" % kernel_id) self.log.debug("Kernel args: %r" % kwargs) # register callback for failed auto-restart @@ -99,12 +74,23 @@ class MappingKernelManager(MultiKernelManager): def shutdown_kernel(self, kernel_id, now=False): """Shutdown a kernel by kernel_id""" + i = 0 + for kernel in self.kernels: + if kernel['kernel_id'] == kernel_id: + del self.kernels[i] + i = i+1 super(MappingKernelManager, self).shutdown_kernel(kernel_id, now=now) - self.delete_mapping_for_kernel(kernel_id) + + def kernel_model(self, kernel_id, ws_url): + model = {"kernel_id":kernel_id, "ws_url": ws_url} + self.kernels.append(model) + return model + + def list_kernels(self): + return self.kernels # override _check_kernel_id to raise 404 instead of KeyError def _check_kernel_id(self, kernel_id): """Check a that a kernel_id exists and raise 404 if not.""" if kernel_id not in self: raise web.HTTPError(404, u'Kernel does not exist: %s' % kernel_id) -