114 votes

Comment obtenir le nom actuel d'IPython / Jupyter Notebook ?

J'essaie d'obtenir le nom actuel du NoteBook lors de l'exécution du notebook IPython. Je sais que je peux le voir en haut du notebook. Ce que je cherche, c'est quelque chose comme

currentNotebook = IPython.foo.bar.notebookname()

J'ai besoin de récupérer le nom dans une variable.

50voto

Mahmoud Elagdar Points 496

en complétant les réponses précédentes,

pour obtenir le nom du carnet de notes, tapez ce qui suit dans une cellule :

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

cela vous donne le nom du fichier dans nb_name

pour obtenir le chemin complet, vous pouvez utiliser la formule suivante dans une cellule séparée :

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

42voto

jfb Points 31

J'ai ce qui suit qui fonctionne avec IPython 2.0. J'ai observé que le nom du carnet de notes est stocké comme la valeur de l'attribut 'data-notebook-name' dans le <body> de la page. L'idée est donc d'abord de demander à Javascript de récupérer l'attribut -- les javascripts peuvent être invoqués depuis une cellule de code grâce à la fonction %%javascript magique. Il est ensuite possible d'accéder à la variable Javascript par un appel au noyau Python, avec une commande qui définit une variable Python. Comme cette dernière variable est connue du noyau, on peut y accéder dans d'autres cellules également.

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

A partir d'une cellule de code Python

print(theNotebook)

Out[ ] : HowToGetTheNameOfTheNoteBook.ipynb

Un défaut de cette solution est que lorsqu'on change le titre (nom) d'un cahier, ce nom ne semble pas être mis à jour immédiatement (il y a probablement une sorte de cache) et il est nécessaire de recharger le cahier pour avoir accès au nouveau nom.

[Edit] À la réflexion, une solution plus efficace consiste à rechercher le champ de saisie du nom de l'ordinateur portable au lieu de l'adresse de l'ordinateur. <body> étiquette. En regardant dans la source, il apparaît que ce champ a pour id "notebook_name". Il est alors possible d'attraper cette valeur par une balise document.getElementById() puis suivez la même approche que ci-dessus. Le code devient, toujours en utilisant la magie du javascript

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

Puis, à partir d'une cellule ipython,

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

Contrairement à la première solution, les modifications du nom du carnet sont mises à jour immédiatement et il n'est pas nécessaire de rafraîchir le carnet.

31voto

Iguananaut Points 2553

Comme nous l'avons déjà dit, vous n'êtes probablement pas censé pouvoir le faire, mais j'ai trouvé un moyen. Il s'agit d'un véritable hack, alors ne vous y fiez pas du tout :

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

J'ai mis à jour ma réponse pour inclure une solution qui "fonctionne" dans IPython 2.0 au moins avec un test simple. Il n'est probablement pas garanti que la réponse soit correcte si plusieurs ordinateurs portables sont connectés au même noyau, etc.

31voto

P.Toccaceli Points 151

Il semble que je ne puisse pas commenter, je dois donc poster ceci comme une réponse.

La solution acceptée par @iguananaut et la mise à jour par @mbdevpl semblent ne pas fonctionner avec les versions récentes de l'ordinateur portable. Je les ai corrigées comme indiqué ci-dessous. Je l'ai vérifié sur Python v3.6.1 + Notebook v5.0.0 et sur Python v3.6.5 et Notebook v5.5.0.

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, ):
    """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 app.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[key_srv_directory],sess['notebook']['path'])
        except:
            pass  # There may be stale entries in the runtime directory 
    return None

Comme indiqué dans la docstring, cela ne fonctionne que lorsqu'il n'y a pas d'authentification ou que l'authentification est basée sur un jeton.

Notez que, comme d'autres l'ont également signalé, la méthode basée sur Javascript ne semble pas fonctionner lors de l'exécution d'un "Run all cells" (mais fonctionne lors de l'exécution "manuelle" des cellules), ce qui a été un obstacle pour moi.

31voto

Bill Points 400

En ipyparams Le paquet peut faire cela assez facilement.

import ipyparams
currentNotebook = ipyparams.notebook_name

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X