Connecting to a remote IPython instance Connecting to a remote IPython instance python python

Connecting to a remote IPython instance


If you want to run code in a kernel from another Python program, the easiest way is to connect a BlockingKernelManager. The best example of this right now is Paul Ivanov's vim-ipython client, or IPython's own terminal client.

The gist:

  • ipython kernels write JSON connection files, in IPYTHONDIR/profile_<name>/security/kernel-<id>.json, which contain information necessary for various clients to connect and execute code.
  • KernelManagers are the objects that are used to communicate with kernels (execute code, receive results, etc.).*

A working example:

In a shell, do ipython kernel (or ipython qtconsole, if you want to share a kernel with an already running GUI):

$> ipython kernel[IPKernelApp] To connect another client to this kernel, use:[IPKernelApp] --existing kernel-6759.json

This wrote the 'kernel-6759.json' file

Then you can run this Python snippet to connect a KernelManager, and run some code:

from IPython.lib.kernel import find_connection_filefrom IPython.zmq.blockingkernelmanager import BlockingKernelManager# this is a helper method for turning a fraction of a connection-file name# into a full path.  If you already know the full path, you can just use thatcf = find_connection_file('6759')km = BlockingKernelManager(connection_file=cf)# load connection info and init communicationkm.load_connection_file()km.start_channels()def run_cell(km, code):    # now we can run code.  This is done on the shell channel    shell = km.shell_channel    print    print "running:"    print code    # execution is immediate and async, returning a UUID    msg_id = shell.execute(code)    # get_msg can block for a reply    reply = shell.get_msg()    status = reply['content']['status']    if status == 'ok':        print 'succeeded!'    elif status == 'error':        print 'failed!'        for line in reply['content']['traceback']:            print linerun_cell(km, 'a=5')run_cell(km, 'b=0')run_cell(km, 'c=a/b')

The output of a run:

running:a=5succeeded!running:b=0succeeded!running:c=a/bfailed!---------------------------------------------------------------------------ZeroDivisionError                         Traceback (most recent call last)/Users/minrk/<ipython-input-11-fb3f79bd285b> in <module>()----> 1 c=a/bZeroDivisionError: integer division or modulo by zero

see the message spec for more information on how to interpret the reply. If relevant, stdout/err and display data will come over km.iopub_channel, and you can use the msg_id returned by shell.execute() to associate output with a given execution.

PS: I apologize for the quality of the documentation of these new features. We have a lot of writing to do.


If you just want to connect interactively, you can use SSH forwarding. I didn't find this documented anywhere on Stack Overflow yet, yet this question comes closest. This answer has been tested on Ipython 0.13. I got the information from this blog post.

  1. Run ipython kernel on the remote machine:

    user@remote:~$ ipython3 kernel[IPKernelApp] To connect another client to this kernel, use:[IPKernelApp] --existing kernel-25333.json
  2. Look at the kernel-25333.json file:

    user@remote:~$ cat ~/.ipython/profile_default/security/kernel-25333.json {  "stdin_port": 54985,   "ip": "127.0.0.1",   "hb_port": 50266,   "key": "da9c7ae2-02aa-47d4-8e67-e6153eb15366",   "shell_port": 50378,   "iopub_port": 49981}
  3. Set up port-forwarding on the local machine:

    user@local:~$ ssh user@remote -f -N -L 54985:127.0.0.1:54985user@local:~$ ssh user@remote -f -N -L 50266:127.0.0.1:50266user@local:~$ ssh user@remote -f -N -L 50378:127.0.0.1:50378user@local:~$ ssh user@remote -f -N -L 49981:127.0.0.1:49981
  4. Copy the kernel-25333.json file to the local machine:

    user@local:~$ rsync -av user@remote:.ipython/profile_default/security/kernel-25333.json ~/.ipython/profile_default/security/kernel-25333.json
  5. Run ipython on the local machine using the new kernel:

    user@local:~$ ipython3 console --existing kernel-25333.jsonPython 3.2.3 (default, Oct 19 2012, 19:53:16)Type "copyright", "credits" or "license" for more information.IPython 0.13.1.rc2 -- An enhanced Interactive Python.?         -> Introduction and overview of IPython's features.%quickref -> Quick reference.help      -> Python's own help system.object?   -> Details about 'object', use 'object??' for extra details.In [1]: import socket; print(socket.gethostname())remote


Update to minrk's answer after the split to jupyter. With jupyter_client (4.1.1)the simplest code is rather something like:

import jupyter_clientcf=jupyter_client.find_connection_file('6759')km=jupyter_client.BlockingKernelClient(connection_file=cf)km.load_connection_file()km.execute('a=5')

Note that:

  • jupyter_client.BlockingKernelClient is also aliased with jupyter_client.client.BlockingKernelClient.
  • the shell (km.shell_channel) does not have the method execute() & get_msg() anymore.

Currently it is quite difficult to find an updated documentation; nothing yet on http://jupyter-client.readthedocs.org/en/latest/ for BlockingKernelClient. Some code in https://github.com/jupyter/jupyter_kernel_test. Any link welcome.