Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sharing a namespace across multiple ipython notebooks

I would like to work with several ipython notebooks at once sharing the same namespace. Is there currently (ipython-1.1.0) a way to do this?

I tried creating different notebooks on the same ipython kernel, but the notebooks don't share a namespace. Also, I've been able to use a terminal console alongside a notebook on the same namespace using the answers in Using IPython console along side IPython notebook, but I couldn't find the notebook equivalent of the --existing argument.

Thanks a lot

like image 980
user3012258 Avatar asked Nov 20 '13 08:11

user3012258


People also ask

How do you link two Jupyter notebooks?

Running a Jupyter Notebook from Another Jupyter NotebookFrom the left Sidebar, select and right-click on the Jupyter notebook that has to be run from another notebook. From the context menu, select Copy Path. Open the Jupyter notebook from which you want to run another notebook. Click Run.


2 Answers

Unfortunately this no longer works, you get error message ipython.kernel replaced by ipython.parallel.

A less elegant way than above to alter this is to change IPython/frontend/html/notebook/kernelmanager.py around line 273 from

kernel_id = self.kernel_for_notebook(notebook_id)

to

kernel_id = None
for notebook_id in self._notebook_mapping:
    kernel_id = self._notebook_mapping[notebook_id]
    break

For Anaconda python, replace start_kernel in kernelmanager.py with

def start_kernel(self, kernel_id=None, path=None, **kwargs):
    global saved_kernel_id
    if saved_kernel_id:
        return saved_kernel_id
    if kernel_id is None:
        kwargs['extra_arguments'] = self.kernel_argv
        if path is not None:
            kwargs['cwd'] = self.cwd_for_path(path)
        kernel_id = super(MappingKernelManager, self).start_kernel(**kwargs)
        self.log.info("Kernel started: %s" % kernel_id)
        self.log.debug("Kernel args: %r" % kwargs)
        self.add_restart_callback(kernel_id,
            lambda : self._handle_kernel_died(kernel_id),
            'dead',
        )
    else:
        self._check_kernel_id(kernel_id)
        self.log.info("Using existing kernel: %s" % kernel_id)
    saved_kernel_id = kernel_id
    return kernel_id

and add

    saved_kernel_id = None

above

    class MappingKernelManager(MultiKernelManager):

True IPython gurus, please supply the correct fix. A lot of people using notebooks want the ability to share the kernel, it's natural, because one notebook quickly grows too big to work with a single complex application, so it is easier to be able to break down the application into multiple notebooks.

Also, gurus, while you're listening, it would be nice to have a collapse-expand feature as in Mathematica so you can only view the part of the notebook you care about and you can zoom out the rest.

like image 60
Lars Ericson Avatar answered Sep 22 '22 12:09

Lars Ericson


The IPython Notebook does not have the equivalent of --existing. Notebooks do not share kernels. It is not a limitation of the notebook itself, it is just a design decision made in the notebook server code. The server code can be modified, for instance, to have all notebooks share the same kernel. You can do this with a little monkeypatching in your IPython configuration. Start by creating a profile:

$ ipython profile create singlekernel
[ProfileCreate] Generating default config file: u'~/.ipython/profile_singlekernel/ipython_config.py'
[ProfileCreate] Generating default config file: u'~/.ipython/profile_singlekernel/ipython_qtconsole_config.py'
[ProfileCreate] Generating default config file: u'~/.ipython/profile_singlekernel/ipython_notebook_config.py'
[ProfileCreate] Generating default config file: u'~/.ipython/profile_singlekernel/ipython_nbconvert_config.py'

and edit $(ipython locate profile singlekernel)/ipython_notebook_config.py to contain:

# Configuration file for ipython-notebook.

c = get_config()

import os
import uuid
from IPython.kernel.multikernelmanager import MultiKernelManager

def start_kernel(self, **kwargs):
    """Minimal override of MKM.start_kernel that always returns the same kernel"""
    kernel_id = kwargs.pop('kernel_id', str(uuid.uuid4()))
    if self.km is None:
        self.km = self.kernel_manager_factory(connection_file=os.path.join(
                self.connection_dir, "kernel-%s.json" % kernel_id),
                parent=self, autorestart=True, log=self.log
    )
    if not self.km.is_alive():
        self.log.info("starting single kernel")
        self.km.start_kernel(**kwargs)
    else:
        self.log.info("reusing existing kernel")
    self._kernels[kernel_id] = self.km
    return kernel_id

MultiKernelManager.km = None
MultiKernelManager.start_kernel = start_kernel

This just overrides the kernel starting mechanism to start only one kernel and return it at every subsequent request, rather than starting a new one for each kernel ID.

Now whenever you start the notebook server with

ipython notebook --profile singlekernel

all of the notebooks in that session will share the same kernel.

like image 41
minrk Avatar answered Sep 23 '22 12:09

minrk