How to Access IPython Notebook on a remote server ?

Feb 18, 2017

My re­search work in­volves a lot of us­ing of IPython Notebook. I usu­ally do it on an of­fice MAC. However I also very of­ten need to ac­cess it from home. After a brief search­ing, I found these three won­der­ful ar­ti­cles on this topic.

I have been do­ing this for a while. But it even­tu­ally comes to me that how good it is if I can make it au­to­matic. So I wrote this python script to do the pro­ce­dures de­scribed in those three ar­ti­cles. I am sure there must be some more el­e­gant way to do this. But this is what I got so far and it works.

import paramiko
import sys
import subprocess
import socket
import argparse

# function to get available port
def get_free_port():
      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      port = s.getsockname()[1]
      return port

# print out the output from paramiko SSH connection
def print_output(output):
    for line in output:

parser = argparse.ArgumentParser(description='Locally open IPython Notebook on remote server\n')
parser.add_argument('-t', '--terminate', dest='terminate', action='store_true', \
                    help='terminate the IPython notebook on remote server')
args = parser.parse_args()

host="***" # host name
user="***" # username

# write a temporary python script to upload to server to execute
# this python script will get available port number

def temp():
    with open('', 'w') as f:
        f.write('import socket\nimport sys\n')
        f.write('def get_free_port():\n')
        f.write('    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n')
        f.write("    s.bind(('localhost', 0))\n")
        f.write('    s.listen(1)\n')
        f.write('    port = s.getsockname()[1]\n')
        f.write('    s.close()\n')
        f.write('    return port\n')

def connect():
    # create SSH client
    client = paramiko.SSHClient()
    client.connect(host, username=user)

    # generate the temp file and upload to server
    ftpClient = client.open_sftp()
    ftpClient.put('', "/tmp/")

    # execute python script on remote server to get available port id
    stdin, stdout, stderr = client.exec_command("python /tmp/")
    stderr_lines = stderr.readlines()

    port_remote = int(stdout.readlines()[0])
    print('REMOTE IPYTHON NOTEBOOK FORWARDING PORT: {}\n'.format(port_remote))

    ipython_remote_command = "source ~/.zshrc;tmux \
                              new-session -d -s remote_ipython_session 'ipython notebook \
                              --no-browser --port={}'".format(port_remote)

    stdin, stdout, stderr = client.exec_command(ipython_remote_command)
    stderr_lines = stderr.readlines()

    if len(stderr_lines) != 0:
        if 'duplicate session: remote_ipython_session' in stderr_lines[0]:
            print("ERROR: \"duplicate session: remote_ipython_session already exists\"\n")


    # delete the temp files on local machine and server'rm -rf', shell=True)
    client.exec_command('rm -rf /tmp/')


    port_local = int(get_free_port())
    print('LOCAL SSH TUNNELING PORT: {}\n'.format(port_local))

    ipython_local_command = "ssh -N -f -L localhost:{}:localhost:{} \
                  ".format(port_local, port_remote), shell=True)

def close():
    # create SSH client
    client = paramiko.SSHClient()
    client.connect(host, username=user)
    stdin, stdout, stderr = client.exec_command("source ~/.zshrc;tmux kill-session -t remote_ipython_session")
    stderr_lines = stderr.readlines()
    if len(stderr_lines) == 0:
        print('Successfully terminate the IPython notebook\n')

if args.terminate:

This script does the fol­low­ing:

  1. Connect to the server us­ing python pack­age paramiko.
  2. Upload a tem­po­rary python script. Use paramiko to ex­e­cute the python script. This script gets an avail­able port on lo­cal­host.
  3. Open Ipython Notebook us­ing the port we get from the last step. I used tmux to do this. And my shell is zsh. You can mod­ify that part of code based on your sit­u­a­tion
  4. On the lo­cal ma­chine, find an avail­able port and cre­ate an SSH tun­nel­ing to port for­ward­ing the port on the re­mote ma­chine to lo­cal ma­chine.

If the script runs suc­cess­fully, you will see some­thing like this.

Run the script

If you want to check does IPython Notebook re­ally runs on the re­mote ma­chine. Use com­mand tmux ls. A tmux ses­sion named remote_ipython_session should ex­ist.

Check the sta­tus

In browser, open http://localhost: 50979. You should be able to ac­cess your ipython note­book. To ter­mi­nate the ipython note­book on the re­mote ma­chines, sim­ply do

Terminate the tun­nel­ing