124 Stimmen

Wie erhalte ich den aktuellen IPython / Jupyter Notebook-Namen?

Ich versuche, den aktuellen Notebook-Namen beim Ausführen des IPython-Notebooks zu erhalten. Ich weiß, dass ich ihn oben im Notebook sehen kann. Wonach ich suche, ist etwas wie

currentNotebook = IPython.foo.bar.notebookname()

Ich muss den Namen in einer Variable erhalten.

0 Stimmen

Was versuchst du damit zu tun? Designmäßig weiß der Kernel (der Teil, der Code ausführt) nichts über das Frontend (der Teil, der Notebooks öffnet).

7 Stimmen

Hallo, ich möchte es mit nbconvert verwenden, um den Prozess der automatischen Umwandlung des Notebooks in Latex/PDF zu automatisieren. Meine Notebooks werden remote ausgeführt. Nach einer Klasse können die Schüler eine PDF-Version ihrer Ergebnisse herunterladen.

1 Stimmen

P.Toccaceli's Antwort funktioniert gut mit den neuesten Versionen von JupyterLab (1.1.4) (Notebook 5.6.0) und erfordert kein Javascript.

4voto

Mehdi Punkte 574

Durch die Modifizierung der Methode von @jfb erhalten Sie die folgende Funktion, die gut auf ipykernel-5.3.4 funktioniert hat.

def getNotebookName():
    display(Javascript('IPython.notebook.kernel.execute("NotebookName = " + "\'"+window.document.getElementById("notebook_name").innerHTML+"\'");'))
    try:
        _ = type(NotebookName)
        return NotebookName
    except:
        return None

Beachten Sie, dass das Anzeigen von JavaScript einige Zeit benötigt, um den Browser zu erreichen, und es einige Zeit dauert, um das JS auszuführen und zum Kernel zurückzukehren. Es mag dumm klingen, aber es ist besser, die Funktion in zwei Zellen auszuführen, wie hier:

nb_name = getNotebookName()

und in der nächsten Zelle:

for i in range(10):
    nb_name = getNotebookName()
    if nb_name is not None:
        break

Wenn Sie jedoch keine Funktion definieren müssen, ist es ratsam, display(Javascript(..)) in einer Zelle auszuführen und den Notebook-Namen in einer anderen Zelle zu überprüfen. Auf diese Weise hat der Browser genügend Zeit, um den Code auszuführen und den Notebook-Namen zurückzugeben.

Wenn es Ihnen nichts ausmacht, eine Bibliothek zu verwenden, ist der zuverlässigste Weg:

import ipynbname
nb_name = ipynbname.name()

2 Stimmen

Die Option mit ipynbname ist die EINZIGE, die einfach ist. Bei allen anderen muss ich mich mit der Installation von IPython, Javablahblah und so weiter befassen. Danke.

0 Stimmen

Ipynbname benötigt 16 Sekunden, um in meinem Minimal-Notebook ausgeführt zu werden.

1 Stimmen

@BSalita - Die neueste Version von ipynbname ist schneller. Du könntest viele alte und veraltete nbserver-Dateien haben, falls du JupyterLab verwendest.

3voto

kenissur Punkte 133

Heutzutage wurde dies als Funktion in IPython implementiert, es gibt eine integrierte "vsc_ipynb_file"-Variable.

Dies ist die Korrektur - https://github.com/microsoft/vscode-jupyter/pull/8531

4 Stimmen

Dieser Kommentar ist irreführend, dies gilt nur für Personen, die VSCode verwenden.

2voto

mirekphd Punkte 2661

Um zu verstehen, warum Sie den Notebook-Namen nicht mit diesen JS-basierten Lösungen abrufen können, führen Sie diesen Code aus und achten Sie auf die Verzögerung, die auftritt, bevor das Meldungsfeld angezeigt wird, nachdem Python die Zelle / das gesamte Notebook ausgeführt hat:

%%javascript

function sayHello() {
    alert('Hallo Welt!');
}

setTimeout(sayHello, 1000);
  • Weitere Informationen

Javascript-Aufrufe sind asynchron und daher nicht garantiert, bevor Python eine andere Zelle ausführt, die den Code enthält und erwartet, dass diese Notebook-Namenvariable bereits erstellt wurde... was zu einem NameError führt, wenn versucht wird, auf nicht vorhandene Variablen zuzugreifen, die den Notebook-Namen enthalten sollten.

Ich vermute, einige Upvotes auf dieser Seite wurden gesperrt, bevor die Wähler feststellen konnten, dass alle auf %%javascript basierenden Lösungen letztendlich nicht funktionieren... wenn die Produzenten- und Konsumentenzellen des Notebooks zusammen ausgeführt werden (oder schnell aufeinanderfolgend).

1voto

Caleb Koch Punkte 363

Angenommen, Sie haben den Host, den Port und den Authentifizierungstoken des Jupyter Notebook-Servers, sollte dies für Sie funktionieren. Es basiert auf dieser Antwort.

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()]

Beispiel Verwendung:

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

1voto

ntg Punkte 10508

Alle auf Json basierenden Lösungen scheitern, wenn wir mehr als eine Zelle gleichzeitig ausführen, da das Ergebnis erst nach dem Ende der Ausführung bereit sein wird (es geht nicht darum, sleep zu verwenden oder irgendwie zu warten, überprüfen Sie es selbst, aber denken Sie daran, den Kernel neu zu starten und alle Tests auszuführen).

Basierend auf früheren Lösungen umgeht dies die Verwendung der %% magic, falls Sie sie mitten in einem anderen Code platzieren müssen:

from IPython.display import display, Javascript

# Hier können Kommentare stehen :)
js_cmd = 'IPython.notebook.kernel.execute(\'nb_name = "\' + IPython.notebook.notebook_name + \'"\')'
display(Javascript(js_cmd))

Für Python 3 wird folgendes basierend auf der Antwort von @Iguananaut und aktualisiert für das neueste Python und möglicherweise mehrere Server funktionieren:

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}]')

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X