Notebook / Extensions / 總覽
===
> #ipython, jupyter notebook, python notebook, jupyterlab, elyra
###### tags: `Jupyter`
###### tags: `Jupyter`, `JupyterLab`, `Notebook`, `Elyra`, `Extension`
<br>
[TOC]
<br>
## 官方文件
- ### [Extensions](https://jupyterlab.readthedocs.io/en/1.2.x/user/extensions.html)
- ### [Extension Developer Guide](https://jupyterlab.readthedocs.io/en/stable/extension/extension_dev.html)
> /en/stable/extension/**extension_dev.html**
- ### [Extension Tutorial](https://jupyterlab.readthedocs.io/en/stable/extension/extension_tutorial.html)
> /en/stable/extension/**extension_tutorial.html**
⇨ 前往:[重點整理](/OMBeTZYqS0W7fs9hdy2-kA) (#example, hello-world, getting started)
⇨ 前往:[跟著官方手冊開發 JupyterLab Extension](https://qrtt1.medium.com/jupyterlab-extension-677ab218ea2f)
- ### [The JupyterLab Interface](https://jupyterlab.readthedocs.io/en/stable/user/interface.html)
> /en/stable/user/interface.html
> - JupyterLab 的 UI 元件
> - Diatango 的圖示
> 
- ### [Common Extension Points](https://jupyterlab.readthedocs.io/en/stable/extension/extension_points.html)
> /en/stable/extension/extension_points.html
> UI 元件對應的擴充用法
<br>
## 推薦文件
- ### [[slide] JupyterLab / Elyra](https://docs.google.com/presentation/d/136w0pgrbbbuEZ_OFY7kJkSIfLfS3ZMRPwdZ5ahLV0xU/edit?usp=sharing)
- ### [10 Jupyter Lab Extensions to Boost Your Productivity](https://towardsdatascience.com/4b3800b7ca2a)
- [JupyterLab-DrawIO](https://github.com/QuantStack/jupyterlab-drawio)
```
conda install -c conda-forge jupyterlab-drawio
```
- [用JupyterLab-drawio画模型图](https://zhuanlan.zhihu.com/p/70908238)
- ### [19 Best JupyterLab Extensions for Machine Learning](https://neptune.ai/blog/jupyterlab-extensions-for-machine-learning)
11. [JupyterLab Voyager](https://github.com/altair-viz/jupyterlab_voyager)
> A JupyterLab MIME renderer extension to view CSV and JSON data in Voyager 2.
- ### [Awesome JupyterLab Extensions](https://towardsdatascience.com/awesome-jupyterlab-extensions-90c2d64d244)
- [jupyterlab / jupyterlab-google-drive](https://github.com/jupyterlab/jupyterlab-google-drive)

- ### [99 ways to extend the Jupyter ecosystem](https://blog.jupyter.org/99-ways-to-extend-the-jupyter-ecosystem-11e5dab7c54)

#letex, context menu
- ### [5 Must Have JupyterLab extension for data science!](https://www.analyticsvidhya.com/blog/2021/05/5-must-have-jupyterlab-extension-for-data-science/)
- ### [5 Extensions That Will Make You Switch to Jupyter Lab](https://towardsdatascience.com/5-extensions-that-will-make-you-switch-to-jupyter-lab-32c6b66ac755)
- ### 口袋名單
- from Diatango
- https://github.com/jtpio/jupyterlab-topbar
- https://github.com/jtpio/jupyterlab-system-monitor
- https://github.com/dask/dask-labextension
這個是用來管理與查看 Dask Cluster 運算資
- [GPU Dashboards in Jupyter Lab](https://medium.com/rapids-ai/gpu-dashboards-in-jupyter-lab-757b17aae1d5)

- [[github] rapidsai / jupyterlab-nvdashboard
](https://github.com/rapidsai/jupyterlab-nvdashboard)
<br>
<hr>
<br>
## [Extension Developer Guide](https://jupyterlab.readthedocs.io/en/stable/extension/extension_dev.html)
### [官方列舉](https://jupyterlab.readthedocs.io/en/stable/extension/extension_dev.html#extension-developer-guide)
- notebooks
- document editors and viewers
- code consoles
- terminals
- themes
- file browser
- contextual help system
- debugger
- settings editor.
- [各種實作範例](https://github.com/jupyterlab/extension-examples)
1. [Commands](https://github.com/jupyterlab/extension-examples#commands)
2. [Command Palette](https://github.com/jupyterlab/extension-examples#command-palette)
3. [Context Menu](https://github.com/jupyterlab/extension-examples#context-menu)
4. [Custom Log Console](https://github.com/jupyterlab/extension-examples#custom-log-console)
5. [Datagrid](https://github.com/jupyterlab/extension-examples#datagrid)
6. [Hello World](https://github.com/jupyterlab/extension-examples#hello-world)
7. [Kernel Messaging](https://github.com/jupyterlab/extension-examples#kernel-messaging)
8. [Kernel Output](https://github.com/jupyterlab/extension-examples#kernel-output)
9. [Launcher](https://github.com/jupyterlab/extension-examples#launcher)
10. [Log Messages](https://github.com/jupyterlab/extension-examples#log-messages)
11. [Main Menu](https://github.com/jupyterlab/extension-examples#main-menu)
12. [React Widget](https://github.com/jupyterlab/extension-examples#react-widget)
13. [Server Hello World](https://github.com/jupyterlab/extension-examples#server-hello-world)
14. [Settings](https://github.com/jupyterlab/extension-examples#settings)
15. [Signals](https://github.com/jupyterlab/extension-examples#signals)
16. [State](https://github.com/jupyterlab/extension-examples#state)
17. [Toolbar Item](https://github.com/jupyterlab/extension-examples#toolbar-item)
18. [Widgets](https://github.com/jupyterlab/extension-examples#widgets)
### 1. Preface
- A JupyterLab extension is a package that contains a number of JupyterLab plugins.
一個 extension 是一個套件,包含多個 plugin
### 2. Cookiecutters
- **提供 app 模板**
- 有 TypeScript 或 JavaScript 腳本,兩種選擇
- **提供 mimerender 模板**
- **提供 theme 模板**
### 3. Overview of Extensions
- **發布方式**
- source extension
- 缺點:需要 Node.js 協助,會耗費大量時間與記憶體
- prebuilt extension (JupyterLab 3.0 才支援)
- pip 套件
- conda 套件
:::info
:bulb: **備註**:
- source 和 prebuilt 可並行發布
- 亦可直接將 prebuilt bundle 複製到適當目錄,優點是免去轉成 python 套件
- 建議使用 pip 套件發布
:::
### 4. Plugins
- ### plugin 類型
- **Application plugins**
- app <-> JupyterLab
- app <-> service <-> 其他 plugin
- plugin 需提供 service
- 可用於:
- main menu, file browser, notebook, console, file editor 等
- **Mime renderer plugins**
- 被載入時,會被 JupyterLab 轉成 Application plugins
- 內建:pdf viewer, JSON viewer, [Vega](https://vega.github.io/vega/usage/) viewer.
[](https://i.imgur.com/FhBJ3vg.png)
- **Theme plugins**
- 內建:淺色和深色主題外掛
- 可變更 css 變數值、font、graphic 等
- ### Application plugins
- Application plugin 是一個 JS 物件
- [Plugins Interacting with Each Other](https://jupyterlab.readthedocs.io/en/stable/extension/extension_dev.html#services)
- **plugin 基本架構**
```typescript=
import {
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
const plugin: JupyterFrontEndPlugin<MyToken> = {
id: 'my-extension:plugin',
activate: activateFunction
};
export default plugin;
```
- `id`
- **類型**:`string`,須唯一
- **值**:`{npm_extension_name}`:`{plugin_name}`
- 一個套件可以包含多個 plugin
- `my_ext:plugin1`
- `my_ext:plugin2`
- `my_ext:plugin3`
- `activate`
- **類型**:`function`, 啟動入口
- **呼叫時間**:plugin 被啟用時
- **參數**:第一個參數固定為 [application object](https://jupyterlab.readthedocs.io/en/stable/extension/extension_dev.html#application-object)
類型:`@jupyterlab/application`:`JupyterFrontEnd`
印出物件:
[](https://i.imgur.com/iuW471q.png)
- **plugin 基本架構 - 具體實作**
```typescript=
import {
JupyterFrontEnd,
JupyterFrontEndPlugin
} from '@jupyterlab/application';
const plugin: JupyterFrontEndPlugin<void> = {
id: 'my-extension:plugin',
autoStart: true,
activate: (app: JupyterFrontEnd) => {
console.log('calling main()')
}
};
export default plugin;
```
- **需要跟其他元件互動的 plugin 架構**
```typescript=
const plugin: JupyterFrontEndPlugin<MyToken> = {
id: 'my-extension:plugin',
autoStart: true,
requires: [ILabShell, ITranslator],
optional: [ICommandPalette],
provides: MyToken,
activate: activateFunction
};
```
- `autoStart`
- **說明**:在 JupyterLab 起來後,要不要自動載入 plugin ?
- **類型**:`boolean`
- **值**
- `true`
- 在 JupyterLab 起來後,就會呼叫該入口點`activate()`
- `false` 或是沒定義該屬性
- 當其他 plugin 請求你的 token 時,才會呼叫的入口點`activate()`
- `provides`
- **說明**:plugin 自己的 token 名稱
- **類型**:`interface` 名稱(?)
- `requires`
- **說明**:需要互動的 service token 清單
- **類型**:`interface` 清單,作為 token 清單
- `optional`
- **說明**:選擇性互動的 service token 清單
- **類型**:`interface` 清單,作為 token 清單
- ### Application Object
- 類型:JupyterFrontEnd
- 用途:作為 activate() 的第一個參數
- 方法:
- commands
用於註冊指令&執行指令
- docRegistry
- restored
應用程式完成載入時,會呼叫此 promise 物件
- serviceManager
> low-level manager for talking to the Jupyter REST API.
- shell
跟應用程式的內容做互動
- ### Plugins Interacting with Each Other
- **術語**
- provider plugin
- 提供 service 給系統的 plugin
- 一個服務可以是任何 JS 值,但通常是 JS 物件
- consumer plugin
請求服務和使用服務的 plugin
- **Token**
- plugin 所提供的 service 由 token 來識別
- **token 類型**
- Lumino Token 類別的實例
- **provider plugin**
- 在 `provide` 屬性定義 token
- 並透過 `activate()` 函數回傳所提供的 service
- **consumer plugin**
- 在 `requires` 或 `optional` 屬性中引用 token
- 當 JupyterLab 透過 `activate()` 實體化 consumer plugin 時,
- 與 token 關聯的服務將被當作參數傳入
- 當 service 不可用時
- 如果在 `requires` 中引用 token ,則會拋出錯誤
- 如果在 `optional` 中引用 token ,則會帶入 `null` 進入
- **何時在 `optional` 中引用 token?**
- 可有可無的 service,例如 status bar,當然擁有會是最好
- **啟動順序**
- JupyterLab 會確保 provider plugin 在 consumer plugin 啟動前先啟動
:::info
:bulb: **token 不使用字串的原因**
- 使用識別字(identifier) 會產生衝突
- 使用 class 名稱因有 package name 當作 namespace 不易產生衝突
- 使用 TypeScript 可啟用類型檢查
:::
- ### Publishing Tokens
- Tokens will need to be deduplicated in JupyterLab—see Deduplication of Dependencies for more details.
- Token 的最佳實作方式
- 一個套件定義 token
- 另一個套件實作 token
- 這麼一來,可以使用相同 token 、不同實作方式,可以用自己的 service 來取代原始 service
- ### Mime Renderer Plugins
- [pdf extension](https://github.com/jupyterlab/jupyterlab/tree/3.2.x/packages/pdf-extension)
- [mp4 extension](https://github.com/jupyterlab/jupyterlab-mp4)
- [cookiecutter for mime renderer extensions](https://github.com/jupyterlab/mimerender-cookiecutter-ts)
- ### Theme plugins
- 暫略
### 5. Source Extensions
### 6. Prebuilt Extensions
- ### 何謂 Prebuilt
- [預編譯頭](https://zh.wikipedia.org/wiki/%E9%A2%84%E7%BC%96%E8%AF%91%E5%A4%B4)
> 以節約在開發過程中編譯器反覆編譯該標頭檔的開銷
- [Android 概念](http://www.powenko.com/wordpress/android-編譯android原始碼到模擬器上執行/)
> 在編譯的部份,要先編譯kernel完後再編android。如果你沒動到kernel,則不需要再重新編譯,可以去prebuilt/android-arm/kernel/ 下找到 kernel-qemu 這個映像檔來用。
- ### package.json metadata
- Output Directory
```json=
"jupyterlab": {
"outputDir": "mypackage/labextension" <-- 相對路徑
}
```
```
- ${outputDir}
- package.json
- static
- *.js
- other files
```
- Custom webpack config
略
- ### Developing a prebuilt extension
- **指令**
`jupyter labextension build`
- **主要入口點(main entry point): `remoteEntry.<hash>.js`**
```
<sys-prefix>/share/jupyter/labextensions/<package-name>
- static
- remoteEntry.<hash>.js
```
- `<sys-prefix>`: `/home/tj/miniconda3/envs/jupyterlab-ext/`
- **開發模式**
- 在 JupyterLab 套建中,建立一個 symbolic link 指向正在開發的套件
```
<sys-prefix>/share/jupyter/labextensions/<package-name>
->
<your_package_name>/<your_package_name>/labextension
```
其中 `labextension` 會包含 `package.json` 那層
```
labextension
+ static/
+ package.json
```
效果同(範例):
```bash=
$ ln -s \
/home/tj/Asus/workplace/jupyter/myextension2/myextension2/labextension \
/home/tj/miniconda3/envs/jupyterlab-ext/share/jupyter/labextensions/myextension2
```
- 指令
```bash=
$ jupyter labextension develop . --overwrite
or
$ pip install -e
# <sys-prefix>/lib/python3.9/site-packages/xxx-link
```
- 隨後
- 改 code + re-build + 更新 JupyterLab, 變更就會生效
- ### Distributing a prebuilt extension
-
### 7. Development workflow for source extensions
<br>
<hr>
<hr>
<br>
## [Common Extension Points](https://jupyterlab.readthedocs.io/en/stable/extension/extension_points.html)
### [Jupyter Front-End Shell](https://jupyterlab.readthedocs.io/en/stable/extension/extension_points.html#jupyter-front-end-shell)
可掛載區域如下:

- ### top (頂層工具列)

<br>

- 透過 rank 控制
```
app.shell.add(terminal, 'top', {rank: 0});
```
- ### menu (頂層工具列一種,具有選單的工具列)

- ### left & right (左側 & 右側邊欄)

- 放置在側邊欄的目的:
- 提供比 main 更持久的使用者界面
- 右側邊欄
- debug
- contextual help
- [contextual help broken for R docs #6928](https://github.com/jupyterlab/jupyterlab/issues/6928)
[](https://i.imgur.com/r3NjJeO.png)
- [[Feature Request] Contextual Help menu #1468](https://github.com/microsoft/vscode-jupyter/issues/1468)
[](https://i.imgur.com/ETadLaR.png)
- ### main (用戶活動的主要工作區域)

- ### down (像是 log 輸出區域, 文件顯示區域)

- ### bottom (底部區域;狀態列之類的)

- ### header (標題區域;橫幅之類的)

- ### header, down, bottom 三種一起出現的機會非常低
[](https://i.imgur.com/ehryFof.png)
- window10
- 範例程式
- 簡易版
```typescript=
Promise.all([app.restored]).then(() => {
app.commands
.execute('terminal:create-new')
.then((terminal) => {
app.shell.add(terminal, 'header');
});
});
```
- 完整版
```typescript=
import * as WidgetModuleType from '@jupyterlab/terminal/lib/widget';
// need to do: $jlpm add @jupyterlab/terminal
...
Promise.all([app.restored]).then(() => {
app.commands
.execute('terminal:create-new')
.then((terminal: WidgetModuleType.Terminal) => {
app.shell.add(terminal, 'header');
});
});
```
<br>
<hr>
<hr>
<br>
## 擴充元件測試
- ### [Menus](https://github.com/jupyterlab/extension-examples/tree/master/main-menu)
⇨ 前往:[重點整理](/OMBeTZYqS0W7fs9hdy2-kA) (#example, hello-world, getting started)
- ### [Settings](https://github.com/jupyterlab/extension-examples/tree/master/settings)
- [schema/settings-example.json](https://github.com/jupyterlab/extension-examples/blob/master/settings/schema/settings-example.json)
- [src/index.ts](https://github.com/jupyterlab/extension-examples/blob/master/settings/src/index.ts)
<br>