100

IPython ノートブックを実行しているときに、現在の NoteBook 名を取得しようとしています。ノートの上部に表示されていることがわかります。私は次のようなものを求めています

currentNotebook = IPython.foo.bar.notebookname()

変数で名前を取得する必要があります。

4

12 に答える 12

43

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>リフレクションでは、より効率的な解決策は、タグの代わりにノートブックの名前の入力フィールドを探すことです。ソースを調べると、このフィールドの ID は "notebook_name" のようです。次に、この値を adocument.getElementById()でキャッチし、上記と同じアプローチに従うことができます。コードは、まだjavascriptマジックを使用しています

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

最初の解決策とは対照的に、ノートブックの名前の変更はすぐに更新され、ノートブックを更新する必要はありません。

于 2014-05-12T21:54:21.440 に答える
28

すでに述べたように、おそらくこれを行うことができるはずではありませんが、私は方法を見つけました。ただし、これは炎上のハックなので、これにまったく依存しないでください。

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 で「機能する」ソリューションを含めました。同じカーネルに複数のノートブックが接続されている場合など、正しい答えが得られるとは限りません。

于 2012-10-24T18:35:29.157 に答える
28

コメントできないようですので、これを回答として投稿する必要があります。

@iguananaut による承認済みのソリューションと @mbdevpl による更新は、ノートブックの最近のバージョンでは機能していないようです。下図のように修正しました。Python v3.6.1 + Notebook v5.0.0 および Python v3.6.5 と Notebook v5.5.0 で確認しました。

import jupyterlab
if jupyterlab.__version__.split(".")[0] == "3":
    from jupyter_server import serverapp as app
    key_srv_directory = 'root_dir'
else : 
    from notebook import notebookapp as app
    key_srv_directory = 'notebook_dir'
import urllib
import json
import os
import ipykernel

def notebook_path(key_srv_directory, ):
    """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 app.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[key_srv_directory],sess['notebook']['path'])
        except:
            pass  # There may be stale entries in the runtime directory 
    return None

docstring に記載されているように、これは認証がない場合、または認証がトークンベースの場合にのみ機能します。

他の人からも報告されているように、「すべてのセルを実行」を実行する場合、Javascript ベースの方法は機能しないように見えることに注意してください (ただし、セルを「手動で」実行する場合は機能します)。

于 2018-09-05T14:16:18.617 に答える
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セルを実行しても何も出力されません。2 番目のPythonセルを実行すると、次のような結果が生成されます。

NOTEBOOK_FULL_PATH:
 /user/zeph/GetNotebookName.ipynb
于 2015-06-19T15:55:59.043 に答える
4

私のノートブックサーバーは変更される可能性があるため、さらに別のハッキーなソリューションです。基本的に、ランダムな文字列を出力して保存し、作業ディレクトリでその文字列を含むファイルを検索します。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)
于 2020-07-28T13:03:15.090 に答える
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}]')
    
于 2020-09-24T05:25:10.563 に答える