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.

28voto

Auf Jupyter 3.0 funktioniert das Folgende. Hier zeige ich den gesamten Pfad auf dem Jupyter-Server, nicht nur den Notebook-Namen:

Um den NOTEBOOK_FULL_PATH im aktuellen Notebook-Front-End zu speichern:

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

Um es dann anzuzeigen:

print("NOTEBOOK_FULL_PATH:\n", NOTEBOOK_FULL_PATH)

Das Ausführen der ersten Javascript-Zelle erzeugt keine Ausgabe. Das Ausführen der zweiten Python-Zelle erzeugt etwas Ähnliches wie:

NOTEBOOK_FULL_PATH:
 /user/zeph/GetNotebookName.ipynb

4 Stimmen

Dies ist sehr sauber. Wie würden Sie den Javascript-Code dann von einer Python-Funktion aus aufrufen?

0 Stimmen

Hmmmm... vielleicht sollten Sie in diesem Fall den Port mit einem Doppelpunkt gefolgt von der Portnummer anhängen?

3 Stimmen

Dies ist ein relativer Pfad, kein vollständiger Pfad

8voto

MartínV Punkte 165

Noch eine hacky Lösung, da sich mein Notebook-Server ändern kann. Im Grunde drucken Sie eine zufällige Zeichenfolge aus, speichern sie und suchen dann nach einer Datei, die diese Zeichenfolge im Arbeitsverzeichnis enthält. Die while-Schleife wird benötigt, weil save_checkpoint asynchron ist.

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)
    # speichert es (Strg+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 Stimmen

Das ist großartig. Andere auf Javascript basierende Lösungen haben in meiner Umgebung (Sagemaker Studio) nicht gut funktioniert. Diese hier schon!

0 Stimmen

Warum benötigt es die "while"-Schleife, warum muss 'grep' so oft neu gestartet werden?

7voto

138 Aspen Punkte 101

Verwende einfach ipynbname, das praktisch ist

#! pip install ipynbname

import ipynbname
nb_fname = ipynbname.name()
nb_path = ipynbname.path()
print(f"{nb_fname=}")
print(f"{nb_path=}")

Ich habe das in https://stackoverflow.com/a/65907473/15497427 gefunden

6voto

tel Punkte 12202

Es gibt noch keinen echten Weg, das in Jupyterlab zu tun. Aber es gibt einen offiziellen Weg, der jetzt unter aktiver Diskussion/Entwicklung steht, Stand August 2021:

https://github.com/jupyter/jupyter_client/pull/656

In der Zwischenzeit scheint es am besten zu sein, auf den api/sessions REST-Endpunkt von jupyter_server zuzugreifen. Hier ist eine bereinigte Version dieses Ansatzes:

from jupyter_server import serverapp
from jupyter_server.utils import url_path_join
from pathlib import Path
import re
import requests

kernelIdRegex = re.compile(r"(?<=kernel-)[\w\d\-]+(?=\.json)")

def getNotebookPath():
    kernelId = kernelIdRegex.search(get_ipython().config["IPKernelApp"]["connection_file"])[0]

    for jupServ in serverapp.list_running_servers():
        for session in requests.get(url_path_join(jupServ["url"], "api/sessions"), params={"token": jupServ["token"]}).json():
            if kernelId == session["kernel"]["id"]:
                return Path(jupServ["root_dir"]) / session["notebook"]['path']

Getestet und funktioniert mit

python==3.9
jupyter_server==1.8.0
jupyterlab==4.0.0a7

1 Stimmen

Ich habe immer an so viele Anwendungen gedacht, den Dateinamen des Notebooks zu kennen (z.B. anhand des Dateinamens könnte man verschiedene Sets von Modulen für ein bestimmtes Notebook importieren). Diese Funktionalität wird dringend benötigt, idealerweise sollte sie vielleicht in das Kernpaket von Jupyter selbst integriert werden.

0 Stimmen

@Ramirez Niemand bei Stackoverflow interessiert sich buchstäblich für deine Meinung. Wenn du jedoch deine Ansichten / Anwendungsfälle in den Diskussionsthread zur Funktion "Notebook-Namen an Kernel übergeben" postest, werden die tatsächlichen Jupyter-Entwickler sie lesen und wahrscheinlich antworten.

0 Stimmen

Danke! Bei mir hat es funktioniert, mit jupyterlab==3.3.4 und Python 3.7

5voto

AntoninX Punkte 21

Wenn Sie Visual Studio Code verwenden:

import IPython ; IPython.extract_module_locals()[1]['__vsc_ipynb_file__']

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