Forked from mbdevpl/getting_notebook_name_for_ipython420_python35.py
Last active
August 20, 2017 05:20
-
-
Save yingted/9b909eff0c8126f882ddcff33634af41 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# solution for: | |
# https://stackoverflow.com/questions/12544056/how-to-i-get-the-current-ipython-notebook-name | |
# | |
# aimed at: | |
# IPython 4.3.0 | |
''' | |
Library for getting the name of a Jupyter notebook from within an IPython | |
kernel launched for the notebook. | |
Probably doesn't work on OS X. | |
Usage: | |
jupyter_notebook_name() | |
''' | |
import json | |
import os | |
import urllib2 | |
import urlparse | |
import IPython | |
from IPython.lib import kernel | |
import subprocess | |
import notebook.notebookapp | |
import contextlib | |
def _iter_listening_sockaddrs(pid): | |
for line in subprocess.check_output(( | |
'lsof', | |
'-p', str(pid), | |
'-a', '-i', 'TCP', | |
'-a', '-s', 'TCP:LISTEN', | |
'-P', | |
'-Fn', | |
)).split(): | |
if not line: | |
continue | |
if line.startswith('n'): | |
yield line[1:] | |
def _sockaddr_to_port(sockaddr): | |
return urlparse.urlparse('http://' + sockaddr + '/').port | |
def _parent_pid_listening_ports(): | |
parent_pid = os.getppid() | |
listening_sockaddrs = _iter_listening_sockaddrs(parent_pid) | |
return set(map(_sockaddr_to_port, listening_sockaddrs)) | |
def _parent_jupyter_api_url(): | |
# Use the parent process's listening ports to rule out some servers. | |
parent_ports = _parent_pid_listening_ports() | |
api_urls = [] | |
for server in notebook.notebookapp.list_running_servers(): | |
url = server['url'] | |
token = server['token'] | |
parsed = urlparse.urlparse(url) | |
if parsed.port not in parent_ports: | |
continue | |
parsed = parsed._replace(query='token=' + urllib2.quote(token)) | |
api_urls.append(parsed) | |
if len(api_urls) != 1: | |
raise Exception('Did not get exactly 1 API URL %(api_urls)s for the listening ports %(parent_ports)s' % locals()) | |
api_url, = api_urls | |
return api_url | |
# https://stackoverflow.com/questions/12544056/how-do-i-get-the-current-ipython-notebook-name | |
def jupyter_notebook_name(): | |
connection_file_path = kernel.get_connection_file() | |
connection_file = os.path.basename(connection_file_path) | |
kernel_id = connection_file.split('-', 1)[1].split('.')[0] | |
api_url = _parent_jupyter_api_url() | |
with contextlib.closing(urllib2.urlopen(api_url._replace(path='/api/sessions').geturl())) as f: | |
sessions = json.load(f) | |
notebook_names = [] | |
for sess in sessions: | |
if sess['kernel']['id'] == kernel_id: | |
notebook_path = sess['notebook']['path'].encode('utf-8') | |
notebook_filename = os.path.basename(notebook_path) | |
notebook_name, _ipynb = os.path.splitext(notebook_filename) | |
notebook_names.append(notebook_name) | |
if len(notebook_names) != 1: | |
raise Exception('Expected exactly one notebook for kernel %(kernel_id)s among the sessions %(sessions)r' % locals()) | |
notebook_name, = notebook_names | |
return notebook_name |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment