From 538b918c251f257d1fd8975ed2f8f3c06b35b1d8 2014-03-29 21:39:15
From: Dale Jung <dale@dalejung.com>
Date: 2014-03-29 21:39:15
Subject: [PATCH] API: Allow NotebookManagers to control kernel startup dir. #5468

---

diff --git a/IPython/html/services/kernels/kernelmanager.py b/IPython/html/services/kernels/kernelmanager.py
index a2fb8ff..5ff0751 100644
--- a/IPython/html/services/kernels/kernelmanager.py
+++ b/IPython/html/services/kernels/kernelmanager.py
@@ -40,7 +40,7 @@ class MappingKernelManager(MultiKernelManager):
         return "IPython.kernel.ioloop.IOLoopKernelManager"
 
     kernel_argv = List(Unicode)
-    
+
     root_dir = Unicode(getcwd(), config=True)
 
     def _root_dir_changed(self, name, old, new):
@@ -60,9 +60,13 @@ class MappingKernelManager(MultiKernelManager):
         """notice that a kernel died"""
         self.log.warn("Kernel %s died, removing from map.", kernel_id)
         self.remove_kernel(kernel_id)
-    
+
     def cwd_for_path(self, path):
         """Turn API path into absolute OS path."""
+        # short circuit for NotebookManagers that pass in absolute paths
+        if os.path.exists(path):
+            return path
+
         os_path = to_os_path(path, self.root_dir)
         # in the case of notebooks and kernels not being on the same filesystem,
         # walk up to root_dir if the paths don't exist
@@ -77,7 +81,7 @@ class MappingKernelManager(MultiKernelManager):
         ----------
         kernel_id : uuid
             The uuid to associate the new kernel with. If this
-            is not None, this kernel will be persistent whenever it is 
+            is not None, this kernel will be persistent whenever it is
             requested.
         path : API path
             The API path (unicode, '/' delimited) for the cwd.
diff --git a/IPython/html/services/notebooks/filenbmanager.py b/IPython/html/services/notebooks/filenbmanager.py
index 8e99bc5..be0b5d8 100644
--- a/IPython/html/services/notebooks/filenbmanager.py
+++ b/IPython/html/services/notebooks/filenbmanager.py
@@ -492,3 +492,7 @@ class FileNotebookManager(NotebookManager):
     
     def info_string(self):
         return "Serving notebooks from local directory: %s" % self.notebook_dir
+
+    def get_kernel_path(self, name, path='', model=None):
+        """ Return the path to start kernel in """
+        return os.path.join(self.notebook_dir, path)
diff --git a/IPython/html/services/notebooks/nbmanager.py b/IPython/html/services/notebooks/nbmanager.py
index dae9d3e..d5b6907 100644
--- a/IPython/html/services/notebooks/nbmanager.py
+++ b/IPython/html/services/notebooks/nbmanager.py
@@ -168,6 +168,10 @@ class NotebookManager(LoggingConfigurable):
     # NotebookManager API part 2: methods that have useable default
     # implementations, but can be overridden in subclasses.
 
+    def get_kernel_path(self, name, path='', model=None):
+        """ Return the path to start kernel in """
+        return path
+
     def increment_filename(self, basename, path=''):
         """Increment a notebook filename without the .ipynb to make it unique.
         
diff --git a/IPython/html/services/sessions/handlers.py b/IPython/html/services/sessions/handlers.py
index c874d9c..7ed47f6 100644
--- a/IPython/html/services/sessions/handlers.py
+++ b/IPython/html/services/sessions/handlers.py
@@ -42,7 +42,7 @@ class SessionRootHandler(IPythonHandler):
     @web.authenticated
     @json_errors
     def post(self):
-        # Creates a new session 
+        # Creates a new session
         #(unless a session already exists for the named nb)
         sm = self.session_manager
         nbm = self.notebook_manager
@@ -62,7 +62,9 @@ class SessionRootHandler(IPythonHandler):
         if sm.session_exists(name=name, path=path):
             model = sm.get_session(name=name, path=path)
         else:
-            kernel_id = km.start_kernel(path=path)
+            # allow nbm to specify kernels cwd
+            kernel_path = nbm.get_kernel_path(name=name, path=path)
+            kernel_id = km.start_kernel(path=kernel_path)
             model = sm.create_session(name=name, path=path, kernel_id=kernel_id)
         location = url_path_join(self.base_url, 'api', 'sessions', model['id'])
         self.set_header('Location', url_escape(location))