通过 API 与 Jupyter Notebooks 互动
Interact with Jupyter Notebooks via API
问题:我想通过 Jupyter API 从另一个应用程序与 Jupyter 交互,特别是我想至少从该应用程序 运行 我的笔记本(对我来说完美的变体是编辑运行之前的一些段落)。我已经阅读 API documentation 但没有找到我需要的内容。
我为此目的使用了具有相同结构(笔记本和段落)的 Apache Zeppelin。
是否有人将 Jupyter 用于我刚才描述的目的?
我认为在您的案例中使用远程 Jupyter Notebook 是过度工程化。
我认为好的方法是将必要的参数传递给 python 具有良好日志记录的程序。
忽略使用 Jupyter API 是否是问题的最佳解决方案(问题中未明确描述),下面的代码执行您的要求:它将远程执行一个 Jupyter notebook http 并得到一些结果。它不是生产就绪的,它更像是一个如何完成的例子。没有用产生大量输出的单元测试它 - 认为它需要调整。
您还可以通过更改代码数组以编程方式change/edit代码。
您需要根据您的配置更改 notebook_path、base 和 headers,详情请参阅代码。
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()
制作此代码所基于的有用链接(如果您需要更多信息,我建议您阅读):
- https://jupyter-client.readthedocs.io/en/latest/messaging.html#python-api
- https://github.com/jupyter/jupyter/wiki/Jupyter-Notebook-Server-API
请注意还有 https://jupyter-client.readthedocs.io/en/stable/index.html,但据我所知它不支持 HTTP 作为传输方式。
作为参考,这适用于 notebook-5.7.4,不确定其他版本。
@vladmihaisima 扩展代码
from websocket import create_connection, WebSocketTimeoutException
while msg_type != "stream":
try:
rsp = json.loads(ws.recv())
print(rsp["msg_type"])
print(rsp)
msg_type = rsp["msg_type"]
if msg_type == "error":
raise Exception(rsp['content']['traceback'][0])
except WebSocketTimeoutException as _e:
print("No output")
return
问题:我想通过 Jupyter API 从另一个应用程序与 Jupyter 交互,特别是我想至少从该应用程序 运行 我的笔记本(对我来说完美的变体是编辑运行之前的一些段落)。我已经阅读 API documentation 但没有找到我需要的内容。
我为此目的使用了具有相同结构(笔记本和段落)的 Apache Zeppelin。
是否有人将 Jupyter 用于我刚才描述的目的?
我认为在您的案例中使用远程 Jupyter Notebook 是过度工程化。
我认为好的方法是将必要的参数传递给 python 具有良好日志记录的程序。
忽略使用 Jupyter API 是否是问题的最佳解决方案(问题中未明确描述),下面的代码执行您的要求:它将远程执行一个 Jupyter notebook http 并得到一些结果。它不是生产就绪的,它更像是一个如何完成的例子。没有用产生大量输出的单元测试它 - 认为它需要调整。
您还可以通过更改代码数组以编程方式change/edit代码。
您需要根据您的配置更改 notebook_path、base 和 headers,详情请参阅代码。
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()
制作此代码所基于的有用链接(如果您需要更多信息,我建议您阅读):
- https://jupyter-client.readthedocs.io/en/latest/messaging.html#python-api
- https://github.com/jupyter/jupyter/wiki/Jupyter-Notebook-Server-API
请注意还有 https://jupyter-client.readthedocs.io/en/stable/index.html,但据我所知它不支持 HTTP 作为传输方式。
作为参考,这适用于 notebook-5.7.4,不确定其他版本。
@vladmihaisima 扩展代码
from websocket import create_connection, WebSocketTimeoutException
while msg_type != "stream":
try:
rsp = json.loads(ws.recv())
print(rsp["msg_type"])
print(rsp)
msg_type = rsp["msg_type"]
if msg_type == "error":
raise Exception(rsp['content']['traceback'][0])
except WebSocketTimeoutException as _e:
print("No output")
return