prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  notebook.start_kernel is undefined
  Hi, in notificationarea.js, when we need to restart a kernel we call `notebook.start_kernel` which doesn't exist.  Not sure how you guys were planning to handle this, but I took a stab at it.
  
  thanks!
  
  
  </issue>
  <code>
  [start of IPython/html/services/sessions/handlers.py]
  1 """Tornado handlers for the sessions web service."""
  2 
  3 # Copyright (c) IPython Development Team.
  4 # Distributed under the terms of the Modified BSD License.
  5 
  6 import json
  7 
  8 from tornado import web
  9 
  10 from ...base.handlers import IPythonHandler, json_errors
  11 from IPython.utils.jsonutil import date_default
  12 from IPython.html.utils import url_path_join, url_escape
  13 from IPython.kernel.kernelspec import NoSuchKernel
  14 
  15 
  16 class SessionRootHandler(IPythonHandler):
  17 
  18     @web.authenticated
  19     @json_errors
  20     def get(self):
  21         # Return a list of running sessions
  22         sm = self.session_manager
  23         sessions = sm.list_sessions()
  24         self.finish(json.dumps(sessions, default=date_default))
  25 
  26     @web.authenticated
  27     @json_errors
  28     def post(self):
  29         # Creates a new session
  30         #(unless a session already exists for the named nb)
  31         sm = self.session_manager
  32         cm = self.contents_manager
  33         km = self.kernel_manager
  34 
  35         model = self.get_json_body()
  36         if model is None:
  37             raise web.HTTPError(400, "No JSON data provided")
  38         try:
  39             name = model['notebook']['name']
  40         except KeyError:
  41             raise web.HTTPError(400, "Missing field in JSON data: notebook.name")
  42         try:
  43             path = model['notebook']['path']
  44         except KeyError:
  45             raise web.HTTPError(400, "Missing field in JSON data: notebook.path")
  46         try:
  47             kernel_name = model['kernel']['name']
  48         except KeyError:
  49             self.log.debug("No kernel name specified, using default kernel")
  50             kernel_name = None
  51 
  52         # Check to see if session exists
  53         if sm.session_exists(name=name, path=path):
  54             model = sm.get_session(name=name, path=path)
  55         else:
  56             try:
  57                 model = sm.create_session(name=name, path=path, kernel_name=kernel_name)
  58             except NoSuchKernel:
  59                 msg = ("The '%s' kernel is not available. Please pick another "
  60                        "suitable kernel instead, or install that kernel." % kernel_name)
  61                 status_msg = '%s not found' % kernel_name
  62                 self.log.warn('Kernel not found: %s' % kernel_name)
  63                 self.set_status(501)
  64                 self.finish(json.dumps(dict(message=msg, short_message=status_msg)))
  65                 return
  66 
  67         location = url_path_join(self.base_url, 'api', 'sessions', model['id'])
  68         self.set_header('Location', url_escape(location))
  69         self.set_status(201)
  70         self.finish(json.dumps(model, default=date_default))
  71 
  72 class SessionHandler(IPythonHandler):
  73 
  74     SUPPORTED_METHODS = ('GET', 'PATCH', 'DELETE')
  75 
  76     @web.authenticated
  77     @json_errors
  78     def get(self, session_id):
  79         # Returns the JSON model for a single session
  80         sm = self.session_manager
  81         model = sm.get_session(session_id=session_id)
  82         self.finish(json.dumps(model, default=date_default))
  83 
  84     @web.authenticated
  85     @json_errors
  86     def patch(self, session_id):
  87         # Currently, this handler is strictly for renaming notebooks
  88         sm = self.session_manager
  89         model = self.get_json_body()
  90         if model is None:
  91             raise web.HTTPError(400, "No JSON data provided")
  92         changes = {}
  93         if 'notebook' in model:
  94             notebook = model['notebook']
  95             if 'name' in notebook:
  96                 changes['name'] = notebook['name']
  97             if 'path' in notebook:
  98                 changes['path'] = notebook['path']
  99 
  100         sm.update_session(session_id, **changes)
  101         model = sm.get_session(session_id=session_id)
  102         self.finish(json.dumps(model, default=date_default))
  103 
  104     @web.authenticated
  105     @json_errors
  106     def delete(self, session_id):
  107         # Deletes the session with given session_id
  108         sm = self.session_manager
  109         sm.delete_session(session_id)
  110         self.set_status(204)
  111         self.finish()
  112 
  113 
  114 #-----------------------------------------------------------------------------
  115 # URL to handler mappings
  116 #-----------------------------------------------------------------------------
  117 
  118 _session_id_regex = r"(?P<session_id>\w+-\w+-\w+-\w+-\w+)"
  119 
  120 default_handlers = [
  121     (r"/api/sessions/%s" % _session_id_regex, SessionHandler),
  122     (r"/api/sessions",  SessionRootHandler)
  123 ]
  124 
  125
  [end of IPython/html/services/sessions/handlers.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/IPython/html/services/sessions/handlers.py b/IPython/html/services/sessions/handlers.py
  --- a/IPython/html/services/sessions/handlers.py
  +++ b/IPython/html/services/sessions/handlers.py
  @@ -106,7 +106,11 @@
       def delete(self, session_id):
           # Deletes the session with given session_id
           sm = self.session_manager
  -        sm.delete_session(session_id)
  +        try:
  +            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()
  
verification_info: {"golden_diff": "diff --git a/IPython/html/services/sessions/handlers.py b/IPython/html/services/sessions/handlers.py\n--- a/IPython/html/services/sessions/handlers.py\n+++ b/IPython/html/services/sessions/handlers.py\n@@ -106,7 +106,11 @@\n     def delete(self, session_id):\n         # Deletes the session with given session_id\n         sm = self.session_manager\n-        sm.delete_session(session_id)\n+        try:\n+            sm.delete_session(session_id)\n+        except KeyError:\n+            # the kernel was deleted but the session wasn't!\n+            raise web.HTTPError(410, \"Kernel deleted before session\")\n         self.set_status(204)\n         self.finish()\n", "issue": "notebook.start_kernel is undefined\nHi, in notificationarea.js, when we need to restart a kernel we call `notebook.start_kernel` which doesn't exist.  Not sure how you guys were planning to handle this, but I took a stab at it.\n\nthanks!\n\n", "before_files": [{"content": "\"\"\"Tornado handlers for the sessions web service.\"\"\"\n\n# Copyright (c) IPython Development Team.\n# Distributed under the terms of the Modified BSD License.\n\nimport json\n\nfrom tornado import web\n\nfrom ...base.handlers import IPythonHandler, json_errors\nfrom IPython.utils.jsonutil import date_default\nfrom IPython.html.utils import url_path_join, url_escape\nfrom IPython.kernel.kernelspec import NoSuchKernel\n\n\nclass SessionRootHandler(IPythonHandler):\n\n    @web.authenticated\n    @json_errors\n    def get(self):\n        # Return a list of running sessions\n        sm = self.session_manager\n        sessions = sm.list_sessions()\n        self.finish(json.dumps(sessions, default=date_default))\n\n    @web.authenticated\n    @json_errors\n    def post(self):\n        # Creates a new session\n        #(unless a session already exists for the named nb)\n        sm = self.session_manager\n        cm = self.contents_manager\n        km = self.kernel_manager\n\n        model = self.get_json_body()\n        if model is None:\n            raise web.HTTPError(400, \"No JSON data provided\")\n        try:\n            name = model['notebook']['name']\n        except KeyError:\n            raise web.HTTPError(400, \"Missing field in JSON data: notebook.name\")\n        try:\n            path = model['notebook']['path']\n        except KeyError:\n            raise web.HTTPError(400, \"Missing field in JSON data: notebook.path\")\n        try:\n            kernel_name = model['kernel']['name']\n        except KeyError:\n            self.log.debug(\"No kernel name specified, using default kernel\")\n            kernel_name = None\n\n        # Check to see if session exists\n        if sm.session_exists(name=name, path=path):\n            model = sm.get_session(name=name, path=path)\n        else:\n            try:\n                model = sm.create_session(name=name, path=path, kernel_name=kernel_name)\n            except NoSuchKernel:\n                msg = (\"The '%s' kernel is not available. Please pick another \"\n                       \"suitable kernel instead, or install that kernel.\" % kernel_name)\n                status_msg = '%s not found' % kernel_name\n                self.log.warn('Kernel not found: %s' % kernel_name)\n                self.set_status(501)\n                self.finish(json.dumps(dict(message=msg, short_message=status_msg)))\n                return\n\n        location = url_path_join(self.base_url, 'api', 'sessions', model['id'])\n        self.set_header('Location', url_escape(location))\n        self.set_status(201)\n        self.finish(json.dumps(model, default=date_default))\n\nclass SessionHandler(IPythonHandler):\n\n    SUPPORTED_METHODS = ('GET', 'PATCH', 'DELETE')\n\n    @web.authenticated\n    @json_errors\n    def get(self, session_id):\n        # Returns the JSON model for a single session\n        sm = self.session_manager\n        model = sm.get_session(session_id=session_id)\n        self.finish(json.dumps(model, default=date_default))\n\n    @web.authenticated\n    @json_errors\n    def patch(self, session_id):\n        # Currently, this handler is strictly for renaming notebooks\n        sm = self.session_manager\n        model = self.get_json_body()\n        if model is None:\n            raise web.HTTPError(400, \"No JSON data provided\")\n        changes = {}\n        if 'notebook' in model:\n            notebook = model['notebook']\n            if 'name' in notebook:\n                changes['name'] = notebook['name']\n            if 'path' in notebook:\n                changes['path'] = notebook['path']\n\n        sm.update_session(session_id, **changes)\n        model = sm.get_session(session_id=session_id)\n        self.finish(json.dumps(model, default=date_default))\n\n    @web.authenticated\n    @json_errors\n    def delete(self, session_id):\n        # Deletes the session with given session_id\n        sm = self.session_manager\n        sm.delete_session(session_id)\n        self.set_status(204)\n        self.finish()\n\n\n#-----------------------------------------------------------------------------\n# URL to handler mappings\n#-----------------------------------------------------------------------------\n\n_session_id_regex = r\"(?P<session_id>\\w+-\\w+-\\w+-\\w+-\\w+)\"\n\ndefault_handlers = [\n    (r\"/api/sessions/%s\" % _session_id_regex, SessionHandler),\n    (r\"/api/sessions\",  SessionRootHandler)\n]\n\n", "path": "IPython/html/services/sessions/handlers.py"}]}