현재 IPython / Jupyter 노트북 이름을 얻으려면 어떻게해야합니까?


85

IPython 노트북을 실행할 때 현재 메모장 이름을 얻으려고합니다. 노트북 상단에서 볼 수 있다는 것을 알고 있습니다. 내가 무엇을 추구하는지

currentNotebook = IPython.foo.bar.notebookname()

변수에 이름을 가져와야합니다.


그것으로 무엇을하려고합니까? 설계 상 커널 (코드를 실행하는 비트)은 프런트 엔드 (노트북을 여는 비트)에 대해 알지 못합니다.
Thomas K

7
안녕하세요, nbconvert와 함께 노트북을 라텍스 / pdf 생성 프로세스로 자동화하고 싶습니다. 내 노트북은 원격으로 실행됩니다. 수업 후 학생들은 결과의 pdf 버전을 다운로드 할 수 있습니다.
Tooblippe 2012 년

1
P.Toccaceli의 답변 은 JupyterLab (1.1.4) (노트북 5.6.0)의 최신 버전에서 잘 작동하며 자바 스크립트가 필요하지 않습니다.
joelostblom


일부는 작업을 수행하고 pip 패키지를 만들었습니다. pypi.org/project/ipynbname install bypip install ipynbname
NeoTT

답변:


24

이미 언급했듯이 당신은 아마도 이것을 할 수 있어야하는 것은 아니지만 방법을 찾았습니다. 그것은 불타는 해킹이므로 전혀 의존하지 마십시오.

import json
import os
import urllib2
import IPython
from IPython.lib import kernel
connection_file_path = kernel.get_connection_file()
connection_file = os.path.basename(connection_file_path)
kernel_id = connection_file.split('-', 1)[1].split('.')[0]

# Updated answer with semi-solutions for both IPython 2.x and IPython < 2.x
if IPython.version_info[0] < 2:
    ## Not sure if it's even possible to get the port for the
    ## notebook app; so just using the default...
    notebooks = json.load(urllib2.urlopen('http://127.0.0.1:8888/notebooks'))
    for nb in notebooks:
        if nb['kernel_id'] == kernel_id:
            print nb['name']
            break
else:
    sessions = json.load(urllib2.urlopen('http://127.0.0.1:8888/api/sessions'))
    for sess in sessions:
        if sess['kernel']['id'] == kernel_id:
            print sess['notebook']['name']
            break

최소한 간단한 테스트로 IPython 2.0에서 "작동"하는 솔루션을 포함하도록 내 대답을 업데이트했습니다. 동일한 커널에 연결된 노트북이 여러 개인 경우 정답을 보장 할 수 없습니다.


connection_file_path = kernel.get_connection_file ()이 더 이상 작동하지 않습니다. 파일 이름은 arg가 필요합니다.
Purrell

2
일부 업데이트 : from IPython.lib import kernel지금 대신 from IPython import kernel. 또한 사전에 'name'키를 사용하는 대신 'path'키를 사용하십시오.
Tristan Reid

1
답변자 자신이 광고 한대로이 답변은 최신 IPython에서 작동하지 않습니다. : 나는 파이썬 3.5 IPython 4.2.0와 함께 작동하는 것 같다 버전 만든 gist.github.com/mbdevpl/f97205b73610dd30254652e7817f99cb
mbdevpl

1
버전 4.3.0부터는 인증 토큰을 제공해야합니다. 이것은를 사용하여 검색 할 수 있습니다 notebook.notebookapp.list_running_servers().
yingted aug

1
여러 서버가 실행중인 경우 커널의 상위 프로세스가 수신하는 포트를 확인할 수 있습니다. 그러면 연결할 서버를 알 수 있습니다 (또는 모든 로컬 Jupyter 서버에 연결하여 커널을 실행중인 것을 확인할 수 있습니다).
yingted

40

IPython 2.0에서 작동하는 다음이 있습니다. 나는 노트북의 이름 속성의 값으로 저장되는 것을 관찰 'data-notebook-name'에서 <body>페이지의 태그입니다. 따라서 아이디어는 먼저 Javascript에 속성을 검색하도록 요청하는 것입니다 %%javascript. 즉, 마술 덕분에 코드 셀에서 JavaScript를 호출 할 수 있습니다 . 그런 다음 Python 변수를 설정하는 명령을 사용하여 Python 커널에 대한 호출을 통해 Javascript 변수에 액세스 할 수 있습니다. 이 마지막 변수는 커널에서 알 수 있으므로 다른 셀에서도 액세스 할 수 있습니다.

%%javascript
var kernel = IPython.notebook.kernel;
var body = document.body,  
    attribs = body.attributes;
var command = "theNotebook = " + "'"+attribs['data-notebook-name'].value+"'";
kernel.execute(command);

Python 코드 셀에서

print(theNotebook)

Out [] : HowToGetTheNameOfTheNoteBook.ipynb

이 솔루션의 결함은 노트북의 제목 (이름)을 변경하면이 이름이 즉시 업데이트되지 않는 것처럼 보이고 (아마도 일종의 캐시가 있음) 노트북에 액세스하려면 노트북을 다시로드해야한다는 것입니다. 새로운 이름.

[편집] 리플렉션에서보다 효율적인 솔루션은 <body>태그 대신 노트북 이름 입력 필드를 찾는 것입니다 . 소스를 살펴보면이 필드에 "notebook_name"ID가있는 것으로 보입니다. 그러면이 값을 a로 포착 document.getElementById()한 다음 위와 동일한 접근 방식을 따를 수 있습니다. 코드는 여전히 자바 스크립트 마법을 사용합니다.

%%javascript
var kernel = IPython.notebook.kernel;
var thename = window.document.getElementById("notebook_name").innerHTML;
var command = "theNotebook = " + "'"+thename+"'";
kernel.execute(command);

그런 다음 ipython 셀에서

In [11]: print(theNotebook)
Out [11]: HowToGetTheNameOfTheNoteBookSolBis

첫 번째 솔루션과 달리 노트북 이름 수정은 즉시 업데이트되며 노트북을 새로 고칠 필요가 없습니다.


내가 뭔가를 놓쳤을 수도 있지만 파이썬에서 자바 스크립트 코드를 어떻게 호출합니까?
Artjom B.

7
또한 자바 스크립트 객체에 적용된 표시 방법을 사용하여 파이썬 내에서 자바 스크립트를 호출 할 수 있습니다.def getname(): display(Javascript('IPython.notebook.kernel.execute("theNotebook = " + "\'"+IPython.notebook.notebook_name+"\'");'))
Jakob

노트북의 경로를 얻으려면 어떻게 수정합니까?
Pedro M Duarte

@PedroMDuarte : 위 스크립트에서 'thename'에 대한 javascript의 IPython.notebook.notebook_path를 사용하여 해당 값을 얻을 수 있습니다.
Tristan Reid

1
JS 속임수없이 노트북 경로를 얻으려면 :globals()['_dh'][0]
germ

38

이전 답변에 추가,

노트북 이름을 얻으려면 셀에서 다음을 실행하십시오.

%%javascript
IPython.notebook.kernel.execute('nb_name = "' + IPython.notebook.notebook_name + '"')

이것은 nb_name의 파일 이름을 얻습니다.

그런 다음 전체 경로를 얻으려면 별도의 셀에서 다음을 사용할 수 있습니다.

import os
nb_full_path = os.path.join(os.getcwd(), nb_name)

1
사용 IPython.notebook.notebook_name은 다음을 사용하여 수행 할 수 있습니다%%javascript IPython.notebook.kernel.execute('notebookName = ' + '"' + IPython.notebook.notebook_name + '"')
jfb

9
어떤 이유로 이것은 자바 스크립트 셀을 "수동으로"실행하는 경우에만 작동합니다. 전체 노트북을 실행하면 두 번째 셀이 실패합니다. 왜 그런지 아세요?
Pierre-Antoine

나는 어떤 이유로 변수가 자바 스크립트에서 수정 된 다음 동일한 호출에서 순수한 파이썬에서 액세스되면 파이썬 버전은 업데이트를 보지 못하고 자바 스크립트 버전을 대체합니다. 따라서 자바 스크립트 셀을 맨 위로 이동하고 실행 한 다음 "셀> 모든 벨로우 실행"을 사용할 수 있습니다.
Mahmoud Elagdar

2
실제로 자바 스크립트가 필요한 이유는 무엇입니까? 더 이상 원주민은 없습니까?
matanster

1
Jupyter Lab에서 실패 :Javascript Error: IPython is not defined
magicrebirth

27

Jupyter 3.0에서는 다음이 작동합니다. 여기에서는 노트북 이름뿐만 아니라 Jupyter 서버의 전체 경로를 보여줍니다.

NOTEBOOK_FULL_PATH현재 노트북 프런트 엔드에을 저장하려면 :

%%javascript
var nb = IPython.notebook;
var kernel = IPython.notebook.kernel;
var command = "NOTEBOOK_FULL_PATH = '" + nb.base_url + nb.notebook_path + "'";
kernel.execute(command);

그런 다음이를 표시하려면 :

print("NOTEBOOK_FULL_PATH:\n", NOTEBOOK_FULL_PATH)

첫 번째 Javascript 셀을 실행하면 출력이 생성되지 않습니다. 두 번째 Python 셀을 실행 하면 다음과 같은 결과가 생성됩니다.

NOTEBOOK_FULL_PATH:
 /user/zeph/GetNotebookName.ipynb

4
이것은 매우 깨끗합니다. 그렇다면 파이썬 함수에서 자바 스크립트 코드를 어떻게 호출할까요?
Lukas 2015 년

흠 ...이 경우 포트에 콜론과 포트 번호를 붙여야할까요?
Zephaniah Grunschlag

3
이것은 전체 경로가 아닌 상대 경로입니다
Ivelin

여기에는 설정도 포함되지 않습니다 c.NotebookApp.notebook_dir.
sappjw

4
나는 얻고있다 Javascript Error: IPython is not defined. 어떻게 자바 스크립트 용 IPython을로드 할 수 있습니까?
zozo

25

댓글을 달 수없는 것 같아서 답변으로 게시해야합니다.

@iguananaut가 수락 한 솔루션과 @mbdevpl의 업데이트가 최신 버전의 노트북에서 작동하지 않는 것 같습니다. 아래와 같이 수정했습니다. Python v3.6.1 + Notebook v5.0.0과 Python v3.6.5 및 Notebook v5.5.0에서 확인했습니다.

from notebook import notebookapp
import urllib
import json
import os
import ipykernel

def notebook_path():
    """Returns the absolute path of the Notebook or None if it cannot be determined
    NOTE: works only when the security is token-based or there is also no password
    """
    connection_file = os.path.basename(ipykernel.get_connection_file())
    kernel_id = connection_file.split('-', 1)[1].split('.')[0]

    for srv in notebookapp.list_running_servers():
        try:
            if srv['token']=='' and not srv['password']:  # No token and no password, ahem...
                req = urllib.request.urlopen(srv['url']+'api/sessions')
            else:
                req = urllib.request.urlopen(srv['url']+'api/sessions?token='+srv['token'])
            sessions = json.load(req)
            for sess in sessions:
                if sess['kernel']['id'] == kernel_id:
                    return os.path.join(srv['notebook_dir'],sess['notebook']['path'])
        except:
            pass  # There may be stale entries in the runtime directory 
    return None

독 스트링에 명시된 바와 같이 이는 인증이 없거나 인증이 토큰 기반 인 경우에만 작동합니다.

다른 사람들이보고 한 것처럼 Javascript 기반 메서드는 "모든 셀 실행"을 실행할 때 작동하지 않는 것 같지만 (그러나 셀을 "수동으로"실행할 때는 작동 함) 저에게 거래를 방해했습니다.


이것에 대한 도서관이 있습니까?
matanster

Javascript 메소드의 실패는 나에게도 거래를 방해했습니다. 이 대안을 게시 해 주셔서 감사합니다!
gumption

srv [ 'notebook_dir']을 from jupyter_core.paths로 바꿔야합니다. import jupyter_config_dir; traitlets.config에서 가져 오기 Config; c = 구성 (); file_path = os.path.join (jupyter_config_dir (), 'jupyter_notebook_config.py'); exec (open (file_path) .read ()); root_dir = c [ 'FileContentsManager'] [ 'root_dir']
Dave Babbitt

14

ipyparams의 패키지는 아주 쉽게이 작업을 수행 할 수 있습니다.

import ipyparams
currentNotebook = ipyparams.notebook_name

이것은 상단에 받아 들여진 것보다 더 나은 대답 인 것 같습니다.
alejandro

1

Jupyter Notebook 서버의 호스트, 포트 및 인증 토큰이 있다고 가정하면이 기능이 작동합니다. 이 답변을 기반으로합니다 .

import os
import json
import posixpath
import subprocess
import urllib.request
import psutil

def get_notebook_path(host, port, token):
    process_id = os.getpid();
    notebooks = get_running_notebooks(host, port, token)
    for notebook in notebooks:
        if process_id in notebook['process_ids']:
            return notebook['path']

def get_running_notebooks(host, port, token):
    sessions_url = posixpath.join('http://%s:%d' % (host, port), 'api', 'sessions')
    sessions_url += f'?token={token}'
    response = urllib.request.urlopen(sessions_url).read()
    res = json.loads(response)
    notebooks = [{'kernel_id': notebook['kernel']['id'],
                  'path': notebook['notebook']['path'],
                  'process_ids': get_process_ids(notebook['kernel']['id'])} for notebook in res]
    return notebooks

def get_process_ids(name):
    child = subprocess.Popen(['pgrep', '-f', name], stdout=subprocess.PIPE, shell=False)
    response = child.communicate()[0]
    return [int(pid) for pid in response.split()]

사용 예 :

get_notebook_path('127.0.0.1', 17004, '344eb91bee5742a8501cc8ee84043d0af07d42e7135bed90')

0

내 노트북 ​​서버가 바뀔 수 있기 때문에 또 다른 해키 솔루션. 기본적으로 임의의 문자열을 인쇄하고 저장 한 다음 작업 디렉토리에서 해당 문자열을 포함하는 파일을 검색합니다. save_checkpoint가 비동기이기 때문에 while이 필요합니다.

from time import sleep
from IPython.display import display, Javascript
import subprocess
import os
import uuid

def get_notebook_path_and_save():
    magic = str(uuid.uuid1()).replace('-', '')
    print(magic)
    # saves it (ctrl+S)
    display(Javascript('IPython.notebook.save_checkpoint();'))
    nb_name = None
    while nb_name is None:
        try:
            sleep(0.1)
            nb_name = subprocess.check_output(f'grep -l {magic} *.ipynb', shell=True).decode().strip()
        except:
            pass
    return os.path.join(os.getcwd(), nb_name)

0

실행이 끝날 때까지 결과가 준비되지 않기 때문에 한 번에 둘 이상의 셀을 실행하면 모든 Json 기반 솔루션이 실패합니다. 모든 테스트를 실행하십시오)

이전 솔루션을 기반으로하면 다른 코드의 중간에 넣어야하는 경우 %% 매직을 사용하지 않습니다.

from IPython.display import display, Javascript

# can have comments here :)
js_cmd = 'IPython.notebook.kernel.execute(\'nb_name = "\' + IPython.notebook.notebook_name + \'"\')'
display(Javascript(js_cmd))

python 3의 경우 @Iguananaut의 답변에 기반하고 최신 python 및 가능하면 여러 서버로 업데이트 된 다음이 작동합니다.

import os
import json
try:
    from urllib2 import urlopen
except:
    from urllib.request import urlopen
import ipykernel

connection_file_path = ipykernel.get_connection_file()
connection_file = os.path.basename(connection_file_path)
kernel_id = connection_file.split('-', 1)[1].split('.')[0]    
    
running_servers = !jupyter notebook list
running_servers = [s.split('::')[0].strip() for s in running_servers[1:]]
nb_name = '???'
for serv in running_servers:
    uri_parts = serv.split('?')
    uri_parts[0] += 'api/sessions'
    sessions = json.load(urlopen('?'.join(uri_parts)))
    for sess in sessions:
        if sess['kernel']['id'] == kernel_id:
            nb_name = os.path.basename(sess['notebook']['path'])
            break
    if nb_name != '???':
        break
print (f'[{nb_name}]')
    
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.