1 相关包安装
1.1 miniconda安装
# 下载安装包
https://docs.conda.io/en/latest/miniconda.html
1.2 nodejs安装
# 下载地址
https://nodejs.org/en/
1.3 git安装
# 下载地址
https://git-scm.com/download/win
2 扩展开发
2.1 环境搭建
# 文档地址
https://jupyterlab.readthedocs.io/en/stable/extension/extension_tutorial.html#extension-tutorial
# 创建虚拟环境,需要指定下python版本,否则默认版本3.11.0好像不兼容
conda create -n jupyterlab-ext --override-channels --strict-channel-priority -c conda-forge -c nodefaults jupyterlab=3 cookiecutter nodejs jupyter-packaging python==3.10.7
# 指定python版本创建虚拟环境,未指定时使用系统的python
conda create -n nje [python==3.10.7]
# 激活虚拟环境
conda activate jupyterlab-ext
# 删除虚拟环境
conda env remove -n conda activate jupyterlab-ext
2.2 扩展创建
pip install jupyterlab
pip install cookiecutter
cookiecutter https://github.com/jupyterlab/extension-cookiecutter-ts
# 报错时,先cloen下来,再执行
git clone https://github.com/jupyterlab/extension-cookiecutter-ts
cookiecutter extension-cookiecutter-ts
# 各种选项
1 frontend表示用TypeScript编写纯前端的扩展
2 server具有前端和后端部分的扩展
3 theme表示JupyterLab的主题
# -v输出详细信息,-e以可编辑的模式安装项目
# 将扩展的前端部分复制到JupyterLab中。 每次更改时,我们都可以再次运行此命令 将更改复制到 JupyterLab,我们的更改会自动在 JupyterLab中安装?
pip install -ve .
# 报错markupsafe中的moudle找不到,其实是存在的,可能是因为下载的python默认是3.11.0,这个时候应该在创建虚拟环境时,就指定下python版本,在3.9.x~3.10.x之间选择一个版本
jupyter labextension develop --overwrite .
# 这个也报错OsError之类的,有错误参考文档,需要打开win的开发者模式
# 打开第二个终端
conda activate jupyterlab-ext
jupyter lab
2.3 操作
# 查询路径
jupyter --paths
# 列出扩展
jupyter labextension list
# 启用或禁用扩展
jupyter labextension disable/enable my-extension
2.4 扩展开发
2.3.1 增加页面
// 在cookiecutter生成出来的文件夹中 src/index.tx
import {
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
// import { ICommandPalette } from '@jupyterlab/apputils';
import { ICommandPalette, MainAreaWidget } from '@jupyterlab/apputils';
import { Widget } from '@lumino/widgets';
const plugin: JupyterFrontEndPlugin<void> = {
id: 'aa',
autoStart: true,
requires: [ICommandPalette],
activate: (app: JupyterFrontEnd, palette: ICommandPalette) => {
console.log('JupyterLab extension jupyterlab_apod is activated!');
// Create a blank content widget inside of a MainAreaWidget
const content = new Widget();
const widget = new MainAreaWidget({ content });
widget.id = 'apod-jupyterlab';
widget.title.label = 'Astronomy Picture';
widget.title.closable = true;
// Add an application command
const command: string = 'apod:open';
app.commands.addCommand(command, {
label: 'Random Astronomy Picture',
execute: () => {
if (!widget.isAttached) {
// Attach the widget to the main work area if it's not there
app.shell.add(widget, 'main');
}
// Activate the widget
app.shell.activateById(widget.id);
}
});
// Add the command to the palette.
palette.addItem({ command, category: 'Tutorial' });
}
};
export default plugin;
2.3.2 交互式页面顶部增加按钮
src/index.ts
import {
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
import {ButtonExtension} from "./button";
/**
* Initialization data for the aa extension.
*/
const extension: JupyterFrontEndPlugin<void> = {
id: 'aa',
autoStart: true,
activate: (app: JupyterFrontEnd) => {
console.log('JupyterLab extension aa is activated!===================');
let buttonExtension = new ButtonExtension();
app.docRegistry.addWidgetExtension('NoteBook', buttonExtension);
}
};
export default extension;
src/button.ts
import { ToolbarButton } from "@jupyterlab/apputils";
import { DocumentRegistry} from "@jupyterlab/docregistry";
import { INotebookModel, NotebookPanel } from"@jupyterlab/notebook";
import { IDisposable } from "@lumino/disposable";
export class ButtonExtension implements DocumentRegistry.IWidgetExtension<NotebookPanel, INotebookModel> {
createNew(panel: NotebookPanel, context: DocumentRegistry.IContext<INotebookModel>): IDisposable {
let mybutton = new ToolbarButton({
label: 'My Button',
onClick: () => alert('You did it!')
});
panel.toolbar.insertItem(10, 'mybutton', mybutton);
return mybutton;
}
}
命令行中编译执行
# 添加依赖?
jlpm add @jupyterlab/apputils
jlpm add @jupyterlab/application
jlpm add @lumino/widgets
# 编译
jlpm run build
# 前端页面刷新查看效果
2.3.3 主菜单增加按钮
无需ts代码,只需要增加插件设置即可
在package.json中修改jupyterlab,指定扩展目录
"jupyterlab": {
"schemaDir": "schema",
}
schema目录下新增json文件
假如多个json文件中id一样时,为同一个按钮,command相当于一条命令,即将该命令添加到按钮下
{
"jupyter.lab.shortcuts": [],
"title": "demo",
"description": "demo",
"type": "object",
"properties": {},
"jupyter.lab.menus": {
"main": [
{
"id": "menu-demo",
"label": "demo",
"rank": 80,
"items": [
{
"command": "terminal:create-new",
"rank": 0
}
]
}
]
},
"additionalProperties": false
}
2.3.4 workspace
自定义布局可以保存为xx.jupyterlab-workspace文件,该文件其实就是一个json文件
示例文件如下
{
"data": {
"file-browser-filebrowser:cwd": {
"path": ""
},
"dask-dashboard-launcher:individual-progress": {
"data": {
"route": "individual-progress",
"label": "Progress"
}
},
"dask-dashboard-launcher:individual-task-stream": {
"data": {
"route": "individual-task-stream",
"label": "Task Stream"
}
},
"layout-restorer:data": {
"main": {
"dock": {
"type": "split-area",
"orientation": "horizontal",
"sizes": [
0.5,
0.5
],
"children": [
{
"type": "tab-area",
"currentIndex": 0,
"widgets": [
"markdownviewer-widget:Welcome.md"
]
},
{
"type": "split-area",
"orientation": "vertical",
"sizes": [
0.67,
0.33
],
"children": [
{
"type": "tab-area",
"currentIndex": 0,
"widgets": [
"dask-dashboard-launcher:individual-task-stream"
]
},
{
"type": "tab-area",
"currentIndex": 0,
"widgets": [
"dask-dashboard-launcher:individual-progress"
]
}
]
}
]
},
"mode": "multiple-document",
"current": "markdownviewer-widget:Welcome.md"
},
"left": {
"collapsed": false,
"current": "filebrowser",
"widgets": [
"filebrowser",
"running-sessions",
"dask-dashboard-launcher",
"command-palette",
"tab-manager"
]
},
"right": {
"collapsed": true,
"widgets": []
}
},
"markdownviewer-widget:Welcome.md": {
"data": {
"path": "Welcome.md",
"factory": "Markdown Preview"
}
},
"dask-dashboard-launcher": {
"url": "DASK_DASHBOARD_URL",
"cluster": ""
}
},
"metadata": {
"id": "/lab"
}
}