9
votes

Interagir avec Jupyter Notebooks via l'API

Le problème: je veux interagir avec Jupyter à partir d'une autre application via l'API Jupyter, en particulier je veux exécuter mes notebooks à partir de l'application au moins (la variante parfaite pour moi est d'éditer quelques paragraphes avant de l'exécuter). J'ai lu la documentation de l'API mais je n'ai pas trouvé quoi J'ai besoin.

J'ai utilisé à cette fin des Apache Zeppelin qui ont la même structure ( Carnets et paragraphes).

Est-ce que quelqu'un a utilisé Jupyter dans le but que je viens de décrire?


1 commentaires

Vous voudrez peut-être jeter un œil à l'un de ces projets, car ces libs / addons font exactement cela: atom.io/packages / hydrogène OU atom.io/packages/jupyter-notebook . J'espère que cela aide.


3 Réponses :


1
votes

Je pense que l'utilisation de Jupyter Notebook à distance est une sur-ingénierie dans votre cas.

Je vois que le bon moyen est de transmettre les paramètres nécessaires au programme python avec une bonne journalisation.


0 commentaires

17
votes

Ignorant si l'utilisation de l'API Jupyter est la meilleure solution pour le problème (pas clairement décrit dans la question), le code ci-dessous fait ce que vous avez demandé: il exécutera à distance un notebook Jupyter sur http et obtiendra des résultats. Ce n'est pas prêt pour la production, c'est plutôt un exemple de la façon dont cela peut être fait. Je ne l'ai pas testé avec des cellules qui génèrent beaucoup de sortie - je pense qu'il aura besoin d'ajustements.

Vous pouvez également changer / éditer le code par programme en modifiant le tableau de code.

Vous devrez changer le notebook_path , base et en-têtes selon votre configuration, voir le code pour plus de détails.

import json
import requests
import datetime
import uuid
from pprint import pprint
from websocket import create_connection

# The token is written on stdout when you start the notebook
notebook_path = '/Untitled.ipynb'
base = 'http://localhost:9999'
headers = {'Authorization': 'Token 4a72cb6f71e0f05a6aa931a5e0ec70109099ed0c35f1d840'}

url = base + '/api/kernels'
response = requests.post(url,headers=headers)
kernel = json.loads(response.text)

# Load the notebook and get the code of each cell
url = base + '/api/contents' + notebook_path
response = requests.get(url,headers=headers)
file = json.loads(response.text)
code = [ c['source'] for c in file['content']['cells'] if len(c['source'])>0 ]

# Execution request/reply is done on websockets channels
ws = create_connection("ws://localhost:9999/api/kernels/"+kernel["id"]+"/channels",
     header=headers)

def send_execute_request(code):
    msg_type = 'execute_request';
    content = { 'code' : code, 'silent':False }
    hdr = { 'msg_id' : uuid.uuid1().hex, 
        'username': 'test', 
        'session': uuid.uuid1().hex, 
        'data': datetime.datetime.now().isoformat(),
        'msg_type': msg_type,
        'version' : '5.0' }
    msg = { 'header': hdr, 'parent_header': hdr, 
        'metadata': {},
        'content': content }
    return msg

for c in code:
    ws.send(json.dumps(send_execute_request(c)))

# We ignore all the other messages, we just get the code execution output
# (this needs to be improved for production to take into account errors, large cell output, images, etc.)
for i in range(0, len(code)):
    msg_type = '';
    while msg_type != "stream":
        rsp = json.loads(ws.recv())
        msg_type = rsp["msg_type"]
    print(rsp["content"]["text"])

ws.close()

Liens utiles sur la base desquels ce code est créé (que je recommande de lire si vous voulez plus d'informations):

Notez qu'il existe également https: // jupyter-client .readthedocs.io / fr / stable / index.html , mais pour autant que je sache, il ne prend pas en charge HTTP comme transport.

Pour référence, cela fonctionne avec notebook-5.7.4 , pas sûr des autres versions.


4 commentaires

Excellent extrait de code! En guise de note rapide, au cas où vous ne voudriez pas inspecter la sortie de la console pour trouver ce qu'est le jeton jupyter, vous pouvez spécifier le jeton manuellement lors du lancement du notebook en utilisant une variable d'environnement comme celle-ci: $ JUPYTER_TOKEN = this- cahier jupyter is-my-token


Quand j'essaye ceci, while msg_type! = "Stream" semble être une boucle infinie. Je peux cependant voir des messages de type execute_reply , mais ceux-ci ne semblent pas contenir de code. Des idées pourquoi cela pourrait être le cas?


pourquoi ajoutez-vous - / api / kernels, je peux accéder à mon notebook sur le navigateur à partir de l'URL de base si j'ajoute la partie / api / kernels, aucune page n'est trouvée.


@Infinite: il serait peut-être utile de mentionner la version du notebook que vous utilisez. La réponse a environ 2 ans et entre la version mentionnée dans la réponse (5.7.4) et aujourd'hui il y avait environ 20 nouvelles versions - les choses auraient pu changer.



1
votes

Je n'ai pas assez de réputation pour commenter mais (pour moi) la réponse acceptée échoue (bloquée en boucle infinie) s'il y a des cellules de démarque dans le cahier. Ajuster le code

code = [ c['source'] for c in file['content']['cells'] if len(c['source'])>0 and c['cell_type']=='code' ]

à

code = [ c['source'] for c in file['content']['cells'] if len(c['source'])>0 ]

résout ce problème pour moi


0 commentaires