Program Club

현재 IPython 노트북 이름을 얻는 방법

proclub 2020. 12. 11. 18:58
반응형

현재 IPython 노트북 이름을 얻는 방법


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

currentNotebook = IPython.foo.bar.notebookname()

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


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

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에서 "작동"하는 솔루션을 포함하도록 답변을 업데이트했습니다. 동일한 커널에 연결된 노트북이 여러 개인 경우 정답을 보장 할 수 없습니다.


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

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


이전 답변에 추가,

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

%%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)

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

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

@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

As stated in the docstring, this works only when either there is no authentication or the authentication is token-based.

Note that, as also reported by others, the Javascript-based method does not seem to work when executing a "Run all cells" (but works when executing cells "manually"), which was a deal-breaker for me.

참고URL : https://stackoverflow.com/questions/12544056/how-do-i-get-the-current-ipython-notebook-name

반응형