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.

53voto

Mahmoud Elagdar Punkte 820

hinzufügen zu den vorherigen Antworten,

Um den Notebook-Namen zu erhalten, führen Sie das folgende in einer Zelle aus:

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

damit erhalten Sie den Dateinamen in nb_name

Um dann den vollständigen Pfad zu erhalten, können Sie das Folgende in einer separaten Zelle verwenden:

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

1 Stimmen

Unter Verwendung von IPython.notebook.notebook_name kann dies mit %%javascript IPython.notebook.kernel.execute('notebookName = ' + '"' + IPython.notebook.notebook_name + '"') durchgeführt werden.

15 Stimmen

Aus irgendeinem Grund funktioniert dies nur, wenn ich die JavaScript-Zelle "manuell" ausführe. Wenn ich das gesamte Notebook ausführe, schlägt die zweite Zelle fehl. Irgendwelche Ideen warum?

0 Stimmen

Ich vermute, dass aus irgendeinem Grund, wenn eine Variable von JavaScript aus modifiziert wird und dann im selben Aufruf von reinem Python aus aufgerufen wird, die Python-Version das Update nicht sieht und auch die JavaScript-Version ersetzt. Ich vermute daher, dass Sie die JavaScript-Zelle nach oben verschieben, sie ausführen und dann "Zelle> Alle unten ausführen" verwenden können.

42voto

jfb Punkte 679

Ich habe Folgendes, das mit IPython 2.0 funktioniert. Ich habe festgestellt, dass der Name des Notebooks als Wert des Attributs 'data-notebook-name' im -Tag der Seite gespeichert ist. Die Idee ist also zunächst, Javascript zu bitten, das Attribut abzurufen - Javascript kann von einer Codezelle aus dank des %%javascript-Zaubers aufgerufen werden. Dann ist es möglich, auf die Javascript-Variable durch einen Aufruf des Python-Kernels zuzugreifen, mit einem Befehl, der eine Python-Variable setzt. Da diese letzte Variable dem Kernel bekannt ist, kann sie auch in anderen Zellen abgerufen werden.

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

Aus einer Python-Codezelle

print(theNotebook)

Out[ ]: HowToGetTheNameOfTheNoteBook.ipynb

Ein Fehler dieser Lösung ist, dass wenn man den Titel (Namen) eines Notebooks ändert, dann scheint dieser Name nicht sofort aktualisiert zu werden (es gibt wahrscheinlich eine Art Cache), und es ist notwendig, das Notebook neu zu laden, um Zugriff auf den neuen Namen zu erhalten.

[Edit] Bei genauerer Betrachtung ist eine effizientere Lösung, nach dem Eingabefeld für den Namen des Notebooks zu suchen, anstelle des -Tags. Bei genauerem Hinsehen zeigt sich, dass dieses Feld die ID "notebook_name" hat. Es ist dann möglich, diesen Wert mit einem document.getElementById() zu erfassen und dann denselben Ansatz wie oben zu verfolgen. Der Code wird, immer noch mit dem Javascript-Zauber, zu:

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

Dann, von einer ipython-Zelle aus,

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

Im Gegensatz zur ersten Lösung werden Änderungen des Notebooknamens sofort aktualisiert und es ist nicht erforderlich, das Notebook neu zu laden.

0 Stimmen

Vielleicht habe ich etwas verpasst, aber wie ruft man den JavaScript-Code aus Python auf?

7 Stimmen

Es ist auch möglich, das JavaScript von innerhalb von Python aus aufzurufen, indem die Anzeigemethode auf ein JavaScript-Objekt angewendet wird, wie in def getname(): display(Javascript('IPython.notebook.kernel.execute("theNote‌​book = " + "\'"+IPython.notebook.notebook_name+"\'");')) gezeigt.

0 Stimmen

Wie kann ich dies ändern, um den Pfad des Notebooks zu erhalten?

32voto

Iguananaut Punkte 20586

Wie bereits erwähnt, sollten Sie dies wahrscheinlich nicht wirklich können, aber ich habe einen Weg gefunden. Es ist jedoch ein brennender Hack, also verlassen Sie sich überhaupt nicht darauf:

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]

# Aktualisierte Antwort mit Teillösungen für IPython 2.x und IPython < 2.x
if IPython.version_info[0] < 2:
    ## Bin mir nicht sicher, ob es überhaupt möglich ist, den Port für die
    ## Notebook-App zu erhalten; daher einfach den Standard verwenden...
    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

Ich habe meine Antwort aktualisiert, um eine Lösung einzuschließen, die zumindest in IPython 2.0 mit einem einfachen Test "funktioniert". Es ist wahrscheinlich nicht garantiert, die richtige Antwort zu geben, wenn mehrere Notebooks mit demselben Kernel verbunden sind, etc.

0 Stimmen

Connection_file_path = kernel.get_connection_file() funktioniert nicht mehr, Dateiname ist ein erforderliches Argument.

0 Stimmen

Dies hat bei mir auf IPython.__version__ von '0.13.2' gut funktioniert und ich musste keine Dateinamen für die kernel.get_connection_file() angeben.

2 Stimmen

Einige Updates: Anstatt von from IPython.lib import kernel lautet es jetzt nur noch from IPython import kernel. Außerdem sollte anstelle des Schlüssels 'name' in den Wörterbüchern der Schlüssel 'path' verwendet werden. Please note that the translation preserves the HTML tags for code formatting.

31voto

P.Toccaceli Punkte 761

Es scheint, dass ich keinen Kommentar abgeben kann, daher muss ich dies als Antwort posten.

Die akzeptierte Lösung von @iguananaut und das Update von @mbdevpl scheinen mit aktuellen Versionen des Notebooks nicht zu funktionieren. Ich habe es repariert, wie unten gezeigt. Ich habe es auf Python v3.6.1 + Notebook v5.0.0 und auf Python v3.6.5 und Notebook v5.5.0 überprüft.

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, ):
    """Gibt den absoluten Pfad des Notebooks zurück oder None, wenn er nicht bestimmt werden kann
    HINWEIS: Funktioniert nur, wenn die Sicherheit tokenbasiert ist oder es auch kein Passwort gibt
    """
    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']:  # Kein Token und kein Passwort, ähm...
                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  # Es können veraltete Einträge im Laufzeitverzeichnis vorhanden sein
    return None

Wie in der Docstring angegeben, funktioniert dies nur, wenn entweder keine Authentifizierung vorhanden ist oder die Authentifizierung tokenbasiert ist.

Beachten Sie, dass, wie auch von anderen berichtet, die auf Javascript basierende Methode nicht zu funktionieren scheint, wenn ein "Alle Zellen ausführen" ausgeführt wird (funktioniert jedoch, wenn Zellen "manuell" ausgeführt werden), was für mich ein Ausschlusskriterium war.

1 Stimmen

Gibt es dafür eine Bibliothek?

1 Stimmen

Der Ausfall von Javascript-Methoden war auch ein Ausschlussgrund für mich. Danke, dass du dieses Alternative gepostet hast!

0 Stimmen

Ich muss `srv['notebook_dir']` ersetzen durch `from jupyter_core.paths import jupyter_config_dir; from traitlets.config import Config; c = Config(); file_path = os.path.join(jupyter_config_dir(), 'jupyter_notebook_config.py'); exec(open(file_path).read()); root_dir = c['FileContentsManager']['root_dir']`

30voto

Bill Punkte 488

Das ipyparams Paket kann dies ziemlich einfach tun.

import ipyparams
currentNotebook = ipyparams.notebook_name

3 Stimmen

Hallo @bill, ich habe diese Lösung auf einer aktuellen Version von Jupyter Notebook ausprobiert, aber es ist mir nicht gelungen, sie zum Laufen zu bringen. Ich habe einen Beitrag hier erstellt.

9 Stimmen

Ich habe die Lösung mit dem Paket ipynbname gefunden.

0 Stimmen

Wie üblich bei SO - die markierte Antwort ist wahrscheinlich am wenigsten hilfreich und die beste Antwort ist unten begraben

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