2012-09-22 13 views
40

Ich versuche, den aktuellen NoteBook-Namen beim Ausführen des IPython-Notebooks zu erhalten. Ich weiß, dass ich es oben auf dem Notebook sehen kann. Was ich bin nach etwas wieWie bekomme ich den aktuellen IPython Notebook-Namen

currentNotebook = IPython.foo.bar.notebookname() 

Ich muss den Namen in einer Variablen erhalten.

+0

Was versuchen Sie damit? Von Grund auf weiß der Kernel (das Bit, das Code ausführt) nichts über das Frontend (das Bit, das Notebooks öffnet). –

+4

Hallo, Ich möchte es mit Nbconvert verwenden, um das Notebook zu Latex/PDF-Erstellungsprozess zu automatisieren. Meine Notebooks laufen remote. Nach dem Unterricht können die Schüler eine PDF-Version ihrer Ergebnisse herunterladen. – Tooblippe

Antwort

19

Wie schon erwähnt, soll das eigentlich nicht möglich sein, aber ich habe einen Weg gefunden. Es ist ein lodernde Hack allerdings so nicht darauf verlassen überhaupt:

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 meine Antwort aktualisiert, um eine Lösung, die „Werke“ in IPython 2.0 zumindest mit einem einfachen Test aufzunehmen. Es ist wahrscheinlich nicht garantiert, die richtige Antwort zu geben, wenn mehrere Notebooks mit demselben Kernel usw. verbunden sind.

+0

connection_file_path = kernel.get_connection_file() funktioniert nicht mehr, Dateiname ist erforderlich arg. – Purrell

+0

Dies funktionierte für mich auf IPython .__ Version__ von '0.13.2' und ich musste keinen Dateinamen für die kernel.get_connection_file() angeben. – Paul

+1

Einige Updates: Statt 'from IPython.lib import kernel' jetzt ist es nur' from IPython-Import-Kernel'. Anstatt den Schlüssel 'name' in den Wörterbüchern zu verwenden, verwenden Sie auch den Schlüssel 'path' –

20

Ich habe Folgendes, was mit IPython 2.0 funktioniert. Ich habe festgestellt, dass der Name des Notebooks als Wert des Attributs 'data-notebook-name' im <body> Tag der Seite gespeichert wird. Daher ist es die erste Idee, Javascript anzufordern, um das Attribut abzurufen - Javascripts können dank der %%javascript Magie aus einer Codezelle aufgerufen werden. Dann ist es möglich, durch einen Aufruf des Python-Kernels auf die Javascript-Variable mit einem Befehl zuzugreifen, der eine Python-Variable setzt. Da diese letzte Variable aus dem Kernel bekannt ist, kann auf sie auch in anderen Zellen 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); 

Von einem Python-Code Zelle

print(theNotebook) 

Out []: HowToGetTheNameOfTheNoteBook.ipynb

Ein Defekt in dieser Lösung ist, dass, wenn man den Titel ändert (Name) eines Notebooks, dann Dieser Name scheint 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.

[Bearbeiten] Bei einer Betrachtung ist eine effizientere Lösung, nach dem Eingabefeld für den Namen des Notebooks anstelle des Tags <body> zu suchen. Wenn Sie in die Quelle schauen, scheint dieses Feld die ID "notebook_name" zu haben. Es ist dann möglich, diesen Wert durch eine document.getElementById() abzufangen und dann den gleichen Ansatz wie oben zu folgen. Der Code wird, noch die JavaScript-Magie

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

Dann unter Verwendung von einer ipython Zelle,

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

Im Gegensatz zu der ersten Lösung, Änderungen des Namen des Notebooks sofort aktualisiert werden und es besteht keine Notwendigkeit zu aktualisieren das Notebook.

+0

Vielleicht habe ich etwas verpasst, aber wie rufen Sie den Javascript-Code von Python? –

+1

Sie beginnen einfach die Codezelle mit dem magischen '%% javascript' – jfb

+3

Es ist auch möglich, das Javascript innerhalb von Python mit der Anzeigemethode aufzurufen, die auf ein JavaScript-Objekt wie' def getname() angewendet wird: Anzeige (Javascript ('IPython. notebook.kernel.execute ("theNotebook =" + "\ '" + IPython.notebook.notebook_name + "\'"); ')) ' – Jakob

19

Auf Jupyter 3.0 funktioniert das folgende.Hier bin ich den ganzen Weg auf der Jupyter Server zeigt, nicht nur das Notebook Name:

Für die Speicherung der NOTEBOOK_FULL_PATH auf der aktuellen Notebook-:

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

print("NOTEBOOK_FULL_PATH:\n", NOTEBOOK_FULL_PATH) 

Ausführen der ersten Javascript Zelle produziert keine Ausgabe. die zweite Python Zelle Laufen erzeugt so etwas wie:

NOTEBOOK_FULL_PATH: 
/user/zeph/GetNotebookName.ipynb 
+3

Das ist sehr sauber. Wie würdest du den Javascript-Code dann von einer Python-Funktion nennen? – Lukas

+0

Es scheint nur zu funktionieren, wenn Sie keine Portweiterleitung haben – mwm314

+0

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

7

zur vorherigen Antworten Hinzufügen

das Notebook Namen laufen die folgenden in einer Zelle zu erhalten:

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

dieses Ruft den Dateinamen in nb_name

t Um den vollständigen Pfad zu erhalten, können Sie den folgenden Pfad in einer separaten Zelle verwenden:

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

Mit 'IPython.notebook.notebook_name' kann dies mit' '' %% javascript IPython.notebook.kernel.execute ('notebookName =' + '"' + IPython.notebook.notebook_name + '"') '' erreicht werden ' – jfb

Verwandte Themen