Ich versuche, den aktuellen NoteBook-Namen zu erhalten, wenn ich das IPython-Notebook ausführe. Ich weiß, dass ich es oben auf dem Notizbuch sehen kann. Was ich nach so etwas bin
currentNotebook = IPython.foo.bar.notebookname()
Ich muss den Namen in einer Variablen erhalten.
python
jupyter-notebook
ipython
jupyter
jupyter-lab
Tooblippe
quelle
quelle
pip install ipynbname
Antworten:
Wie bereits erwähnt, solltest du das wahrscheinlich nicht wirklich können, aber ich habe einen Weg gefunden. Es ist ein flammender 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] # 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
Ich habe meine Antwort aktualisiert, um eine Lösung aufzunehmen, die in IPython 2.0 zumindest mit einem einfachen Test "funktioniert". Es ist wahrscheinlich nicht garantiert, dass die richtige Antwort gegeben wird, wenn mehrere Notebooks mit demselben Kernel usw. verbunden sind.
quelle
from IPython.lib import kernel
jetzt ist es nurfrom IPython import kernel
. Anstatt den Schlüssel 'Name' in den Wörterbüchern zu verwenden, verwenden Sie auch den Schlüssel 'Pfad'notebook.notebookapp.list_running_servers()
.Ich habe die folgenden, die mit IPython 2.0 funktioniert. Ich habe festgestellt, dass der Name des Notizbuchs als Wert des Attributs
'data-notebook-name'
im<body>
Tag der Seite gespeichert ist . Daher besteht die Idee darin, zuerst Javascript zu bitten, das Attribut abzurufen - Javascripts können dank der%%javascript
Magie aus einer Codezelle aufgerufen werden . Anschließend können Sie über einen Aufruf des Python-Kernels mit einem Befehl, der eine Python-Variable festlegt, auf die Javascript-Variable zugreifen. Da diese letzte Variable aus dem Kernel bekannt ist, kann auch in anderen Zellen darauf zugegriffen 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
Out []: HowToGetTheNameOfTheNoteBook.ipynb
Ein Fehler in dieser Lösung besteht darin, dass, wenn man den Titel (Namen) eines Notizbuchs ändert, dieser Name nicht sofort aktualisiert zu werden scheint (es gibt wahrscheinlich eine Art Cache) und das Notizbuch neu geladen werden muss, um Zugriff auf das zu erhalten neuer Name.
[Bearbeiten] Bei der Reflexion besteht eine effizientere Lösung darin, anstelle des
<body>
Tags nach dem Eingabefeld für den Namen des Notebooks zu suchen . Wenn Sie sich die Quelle ansehen, scheint dieses Feld die ID "notebook_name" zu haben. Es ist dann möglich, diesen Wert mit a zu erfassendocument.getElementById()
und dann den gleichen Ansatz wie oben zu verfolgen. Der Code wird, immer noch mit der Javascript-Magie%%javascript var kernel = IPython.notebook.kernel; var thename = window.document.getElementById("notebook_name").innerHTML; var command = "theNotebook = " + "'"+thename+"'"; kernel.execute(command);
Dann aus einer Ipython-Zelle,
In [11]: print(theNotebook) Out [11]: HowToGetTheNameOfTheNoteBookSolBis
Im Gegensatz zur ersten Lösung werden Änderungen am Namen des Notebooks sofort aktualisiert, und das Notebook muss nicht aktualisiert werden.
quelle
def getname(): display(Javascript('IPython.notebook.kernel.execute("theNotebook = " + "\'"+IPython.notebook.notebook_name+"\'");'))
globals()['_dh'][0]
Hinzufügen zu früheren Antworten,
Um den Namen des Notizbuchs zu erhalten, führen Sie Folgendes in einer Zelle aus:
%%javascript IPython.notebook.kernel.execute('nb_name = "' + IPython.notebook.notebook_name + '"')
Dadurch erhalten Sie den Dateinamen in nb_name
Um den vollständigen Pfad zu erhalten, können Sie Folgendes in einer separaten Zelle verwenden:
import os nb_full_path = os.path.join(os.getcwd(), nb_name)
quelle
IPython.notebook.notebook_name
dieser kann mit Hilfe getan%%javascript IPython.notebook.kernel.execute('notebookName = ' + '"' + IPython.notebook.notebook_name + '"')
Javascript Error: IPython is not defined
Unter Jupyter 3.0 funktioniert Folgendes. Hier zeige ich den gesamten Pfad auf dem Jupyter-Server, nicht nur den Namen des Notebooks:
So speichern Sie das
NOTEBOOK_FULL_PATH
auf dem aktuellen Notebook-Frontend:%%javascript var nb = IPython.notebook; var kernel = IPython.notebook.kernel; var command = "NOTEBOOK_FULL_PATH = '" + nb.base_url + nb.notebook_path + "'"; kernel.execute(command);
So zeigen Sie es an:
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 Folgendes:
quelle
c.NotebookApp.notebook_dir
.Javascript Error: IPython is not defined
. Wie kann ich IPython für Javascript ladenEs scheint, dass ich keinen Kommentar abgeben kann, daher muss ich dies als Antwort posten.
Die von @iguananaut akzeptierte Lösung und das Update von @mbdevpl scheinen mit neueren Versionen des Notebooks nicht zu funktionieren. Ich habe es wie unten gezeigt behoben. 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.
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
Wie in der Dokumentzeichenfolge angegeben, funktioniert dies nur, wenn entweder keine Authentifizierung vorliegt oder die Authentifizierung tokenbasiert ist.
Beachten Sie, dass die Javascript-basierte Methode, wie auch von anderen berichtet, nicht zu funktionieren scheint, wenn "Alle Zellen ausführen" ausgeführt wird (funktioniert jedoch, wenn Zellen "manuell" ausgeführt werden), was für mich ein Deal-Breaker war.
quelle
Das ipyparams- Paket kann dies ziemlich einfach tun.
import ipyparams currentNotebook = ipyparams.notebook_name
quelle
Angenommen, Sie haben den Host, den Port und das 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()]
Anwendungsbeispiel:
get_notebook_path('127.0.0.1', 17004, '344eb91bee5742a8501cc8ee84043d0af07d42e7135bed90')
quelle
Noch eine hackige Lösung, da sich mein Notebook-Server ändern kann. Grundsätzlich drucken Sie eine zufällige Zeichenfolge, speichern sie und suchen dann im Arbeitsverzeichnis nach einer Datei, die diese Zeichenfolge enthält. Die Weile wird benötigt, da 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) # 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)
quelle
Alle Json-basierten Lösungen schlagen fehl, wenn mehr als eine Zelle gleichzeitig ausgeführt wird, da das Ergebnis erst nach dem Ende der Ausführung verfügbar ist (es geht nicht darum, den Ruhezustand zu verwenden oder zu warten, überprüfen Sie es selbst, aber denken Sie daran, den Kernel neu zu starten und alle Tests ausführen)
Basierend auf früheren Lösungen wird die Verwendung der %% -Magie vermieden, falls Sie sie in die Mitte eines anderen Codes stellen müssen:
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))
Für Python 3 funktioniert Folgendes, basierend auf der Antwort von @Iguananaut und aktualisiert für das neueste Python und möglicherweise mehrere Server:
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}]')
quelle