Jupyter Notebook内核共享交互失败求助:WebSocket错误+变量未定义
问题:Python脚本/CLI与Jupyter Notebook共享内核实现双向变量交互失败
目标
实现Python代码(CLI/脚本)与Jupyter Notebook UI共享同一kernel,达成实时双向变量交互。
预期用例
- 在Notebook UI中定义变量:
x = 2 - 从Python脚本/CLI执行
print(x) - 预期输出
2,验证内核共享生效
尝试操作
- 以协作模式启动Jupyter Lab:
jupyter lab --no-browser --IdentityProvider.token=eere --ip=0.0.0.0 --port=14484 --collaborative
- 执行以下Python脚本:
from jupyter_nbmodel_client import NbModelClient, get_jupyter_notebook_websocket_url from jupyter_kernel_client import KernelClient SERVER_URL = "http://localhost:14484" TOKEN = "eere" NOTEBOOK_PATH = "~/Documents/envs/test/kernel_test.ipynb" cell_content = "print(x)" kernel = KernelClient(server_url=SERVER_URL, token=TOKEN) kernel.start() notebook = NbModelClient( get_jupyter_notebook_websocket_url(server_url=SERVER_URL, token=TOKEN, path=NOTEBOOK_PATH) ) await notebook.start() cell_index = notebook.add_code_cell(cell_content) notebook.execute_cell(cell_index, kernel)
错误输出
Websocket client stopped. Traceback (most recent call last): File "~Documents/envs/test/.really_delete/lib/python3.10/site-packages/jupyter_nbmodel_client/client.py", line 86, in _listen_to_websocket async for message in websocket: File "~Documents/envs/test/.really_delete/lib/python3.10/site-packages/websockets/asyncio/connection.py", line 242, in __aiter__ yield await self.recv() File "~Documents/envs/test/.really_delete/lib/python3.10/site-packages/websockets/asyncio/connection.py", line 322, in recv raise self.protocol.close_exc from self.recv_exc websockets.exceptions.ConnectionClosedError: sent 1002 (protocol error) invalid status code; no close frame received Document ws://localhost:14484/api/collaboration/room/json:notebook:54aee93a-b50f-4190-820f-c5306b218eb8?sessionId=7781e065-b341-4f85-8a56-f4caa4190de6&token=eere not yet synced. {'execution_count': 1, 'outputs': [{'output_type': 'error', 'ename': 'NameError', 'evalue': "name 'x' is not defined", 'traceback': ['\x1b[0;31m---------------------------------------------------------------------------\x1b[0m', '\x1b[0;31mNameError\x1b[0m Traceback (most recent call last)', 'Cell \x1b[0;32mIn[1], line 1\x1b[0m\n\x1b[0;32m----> 1\x1b[0m \x1b[38;5;28mprint\x1b[39m(\x1b[43mx\x1b[49m)\n', "\x1b[0;31mNameError\x1b[0m: name 'x' is not defined"]}], 'status': 'error'}
解决方案
1. 修复WebSocket连接问题
- 确保
jupyter_nbmodel_client和jupyter_kernel_client版本与当前Jupyter Lab版本兼容,优先使用匹配的最新稳定版 - 替换Notebook路径中的
~为绝对路径(如/home/username/Documents/envs/test/kernel_test.ipynb),避免路径解析错误导致同步失败 - 增加文档同步等待逻辑,确保Notebook完全同步后再执行代码:
await notebook.start() # 等待文档同步完成 while not notebook.is_synced(): await asyncio.sleep(0.1)
2. 确保连接Notebook已有的内核
当前代码中KernelClient.start()会创建新内核,而非复用Notebook正在使用的内核。需获取Notebook的内核ID再连接:
# 替换原kernel初始化代码 # 获取Notebook关联的内核信息 kernel_info = await notebook.get_kernel_info() kernel = KernelClient(server_url=SERVER_URL, token=TOKEN, kernel_id=kernel_info['id']) kernel.connect()
同时需确认Notebook UI已启动并连接内核,且x = 2已执行完毕。
3. 简化替代方案(无需协作模式)
若协作模式的WebSocket问题难以排查,可直接使用官方jupyter_client库连接现有内核:
- 在Notebook中执行
%connect_info,获取内核连接信息(包含kernel_id、各端口号等) - 在脚本中使用以下代码连接并执行:
from jupyter_client import BlockingKernelClient # 替换为%connect_info输出的实际连接参数 kernel_config = { "shell_port": 12345, "iopub_port": 12346, "stdin_port": 12347, "control_port": 12348, "hb_port": 12349, "ip": "127.0.0.1", "key": "abcdef123456", "transport": "tcp", "signature_scheme": "hmac-sha256", "kernel_name": "" } client = BlockingKernelClient() client.load_connection_info(kernel_config) client.start_channels() # 执行代码并捕获输出 msg_id = client.execute("print(x)") for msg in client.get_iopub_msg(): if msg['parent_header']['msg_id'] == msg_id: if 'content' in msg and 'text' in msg['content']: print(msg['content']['text']) client.stop_channels()
内容的提问来源于stack exchange,提问作者Morpheus
相关产品推荐
相关产品推荐

