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.

28voto

Sur Jupyter 3.0, ce qui suit fonctionne. Ici, j'affiche le chemin complet sur le serveur Jupyter, pas seulement le nom du notebook :

Pour enregistrer le NOTEBOOK_FULL_PATH sur la façade de l'ordinateur portable actuel :

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

Pour ensuite l'afficher :

print("NOTEBOOK_FULL_PATH:\n", NOTEBOOK_FULL_PATH)

L'exécution de la première Javascript La cellule ne produit aucun résultat. L'exécution de la deuxième Python La cellule produit quelque chose comme :

NOTEBOOK_FULL_PATH:
 /user/zeph/GetNotebookName.ipynb

7voto

MartínV Points 145

Encore une autre solution bricolée puisque le serveur de mon ordinateur portable peut changer. En gros, vous imprimez une chaîne de caractères aléatoire, vous la sauvegardez et vous recherchez ensuite un fichier contenant cette chaîne dans le répertoire de travail. Le while est nécessaire car save_checkpoint est asynchrone.

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)

2voto

Mehdi Points 324

En modifiant la méthode @jfb, on obtient la fonction ci-dessous qui fonctionne bien sur ipykernel-5.3.4.

def getNotebookName():
    display(Javascript('IPython.notebook.kernel.execute("NotebookName = " + "\'"+window.document.getElementById("notebook_name").innerHTML+"\'");'))
    try:
        _ = type(NotebookName)
        return NotebookName
    except:
        return None

Nota que le javascript d'affichage prendra un certain temps pour atteindre le navigateur, et qu'il faudra un certain temps pour exécuter le JS et revenir au noyau. Je sais que cela peut paraître stupide, mais il est préférable d'exécuter la fonction en deux cellules, comme ceci :

nb_name = getNotebookName()

et dans la cellule suivante :

for i in range(10):
    nb_name = getNotebookName()
    if nb_name is not None:
        break

Cependant, si vous n'avez pas besoin de définir une fonction, la méthode la plus sage est d'exécuter display(Javascript(..)) dans une cellule, et vérifier le nom du cahier dans une autre cellule. De cette façon, le navigateur a suffisamment de temps pour exécuter le code et renvoyer le nom du cahier.

Si l'utilisation d'une bibliothèque ne vous dérange pas, la méthode la plus robuste est la suivante :

import ipynbname
nb_name = ipynbname.name()

1voto

Caleb Koch Points 159

En supposant que vous avez l'hôte, le port et le jeton d'authentification du serveur Jupyter Notebook, cela devrait fonctionner pour vous. C'est basé sur cette réponse .

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()]

Exemple d'utilisation :

get_notebook_path('127.0.0.1', 17004, '344eb91bee5742a8501cc8ee84043d0af07d42e7135bed90')

0voto

ntg Points 498

Toutes les solutions basées sur Json échouent si nous exécutons plus d'une cellule à la fois. parce que le résultat ne sera pas prêt avant la fin de l'exécution. (ce n'est pas une question d'utilisation de sleep ou d'attente, vérifiez vous-même mais n'oubliez pas de redémarrer le noyau et d'exécuter tous les tests).

Sur la base des solutions précédentes, cela évite d'utiliser la magie du %% au cas où vous auriez besoin de le placer au milieu d'un autre code :

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))

Pour python 3, ce qui suit, basé sur la réponse de @Iguananaut et mis à jour pour le dernier python et éventuellement plusieurs serveurs, fonctionnera :

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}]')

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