VSCode扩展开发:如何连接当前Jupyter Notebook内核?
解决方案:VSCode Jupyter扩展访问现有内核DataFrame数据
错误原因
你直接调用getKernelService失败,是因为ms-toolsai.jupyter扩展的内部内核服务API不对外公开,第三方扩展无权限直接访问,因此触发权限校验报错。
正确解决方案
方案1:通过Jupyter公共API与当前运行内核交互
利用Jupyter扩展提供的公共API获取当前活动笔记本的内核,通过执行代码片段的方式提取DataFrame数据(转为JSON便于传输)。
示例代码:
import * as vscode from 'vscode'; // 获取当前活动笔记本对应的Jupyter内核 async function getActiveJupyterKernel() { const jupyterExt = vscode.extensions.getExtension('ms-toolsai.jupyter'); if (!jupyterExt) throw new Error('Jupyter扩展未安装'); await jupyterExt.activate(); const activeNotebook = vscode.window.activeNotebookEditor?.document; if (!activeNotebook) throw new Error('无活动笔记本'); return await jupyterExt.exports.getKernelForDocument(activeNotebook.uri); } // 从内核中获取指定名称的DataFrame数据 async function fetchDataFrame(kernel: any, dfName: string) { // 构造代码:将DataFrame转为JSON格式 const fetchCode = `import pandas as pd; ${dfName}.to_json(orient='split')`; // 发送执行请求到内核 const executionResult = await kernel.requestExecute({ code: fetchCode, silent: false, storeHistory: false }); // 解析返回结果 if (executionResult.content.status === 'ok' && executionResult.content.data['application/json']) { return JSON.parse(executionResult.content.data['application/json']); } throw new Error('获取DataFrame数据失败'); } // 调用示例 async function main() { try { const kernel = await getActiveJupyterKernel(); const dfData = await fetchDataFrame(kernel, 'myDataFrame'); // 替换为你的DataFrame名称 console.log('DataFrame数据:', dfData); } catch (err) { console.error(err); } }
方案2:关联现有内核的Notebook Controller实现
你之前新建Controller得到全新内核,是因为没有关联到已运行的Jupyter内核实例。正确做法是注册Controller后,将执行请求转发到现有内核:
import * as vscode from 'vscode'; async function registerLinkedJupyterController() { const jupyterExt = vscode.extensions.getExtension('ms-toolsai.jupyter'); if (!jupyterExt) return; await jupyterExt.activate(); // 获取所有运行中的Jupyter内核 const runningKernels = await jupyterExt.exports.getRunningKernels(); if (runningKernels.length === 0) return; // 选择目标内核(这里取第一个,可根据需求调整) const targetKernel = runningKernels[0]; // 创建关联现有内核的Notebook Controller const controller = vscode.notebooks.createNotebookController( 'linked-jupyter-controller', 'jupyter-notebook', '关联现有Jupyter内核控制器' ); // 实现执行逻辑,转发请求到现有内核 controller.executeHandler = async (cells) => { for (const cell of cells) { const execution = controller.createNotebookCellExecution(cell); execution.start(); try { const result = await targetKernel.requestExecute({ code: cell.document.getText(), silent: false, storeHistory: true }); if (result.content.status === 'ok') { execution.end(true); // 处理并显示输出结果 if (result.content.data) { cell.outputs = [ new vscode.NotebookCellOutput([ vscode.NotebookCellOutputItem.json(result.content.data) ]) ]; } } else { execution.end(false); // 显示错误信息 cell.outputs = [ new vscode.NotebookCellOutput([ vscode.NotebookCellOutputItem.text(`${result.content.ename}: ${result.content.evalue}`) ]) ]; } } catch (err) { execution.end(false); cell.outputs = [ new vscode.NotebookCellOutput([ vscode.NotebookCellOutputItem.text(String(err)) ]) ]; } } }; }
注意事项
- 必须在扩展的
package.json中声明对Jupyter扩展的依赖,确保加载顺序:"extensionDependencies": [ "ms-toolsai.jupyter" ] - Jupyter扩展的公共API可能随版本更新变化,需注意兼容性;
- 执行代码获取DataFrame时,要确保目标DataFrame存在于当前内核的全局命名空间中,同时处理转换失败、内核未运行等异常场景。
内容的提问来源于stack exchange,提问作者Giselle S
相关产品推荐
相关产品推荐

