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 的圖示 > ![](https://i.imgur.com/ATDMWxS.png) - ### [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) ![](https://i.imgur.com/SkkgThq.png) - ### [99 ways to extend the Jupyter ecosystem](https://blog.jupyter.org/99-ways-to-extend-the-jupyter-ecosystem-11e5dab7c54) ![](https://i.imgur.com/Lzj5X5J.png) #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) ![](https://i.imgur.com/Gzmv0LD.png) - [[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)](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)](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) 可掛載區域如下: ![](https://i.imgur.com/jGIaytU.png) - ### top (頂層工具列) ![](https://i.imgur.com/oAur5To.png) <br> ![](https://i.imgur.com/PD4bWN8.png) - 透過 rank 控制 ``` app.shell.add(terminal, 'top', {rank: 0}); ``` - ### menu (頂層工具列一種,具有選單的工具列) ![](https://i.imgur.com/nWJRttf.png) - ### left & right (左側 & 右側邊欄) ![](https://i.imgur.com/d4licaQ.png) - 放置在側邊欄的目的: - 提供比 main 更持久的使用者界面 - 右側邊欄 - debug - contextual help - [contextual help broken for R docs #6928](https://github.com/jupyterlab/jupyterlab/issues/6928) [![](https://i.imgur.com/r3NjJeO.png)](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)](https://i.imgur.com/ETadLaR.png) - ### main (用戶活動的主要工作區域) ![](https://i.imgur.com/b1v0J8n.png) - ### down (像是 log 輸出區域, 文件顯示區域) ![](https://i.imgur.com/btDpzYU.png) - ### bottom (底部區域;狀態列之類的) ![](https://i.imgur.com/YJuosBN.png) - ### header (標題區域;橫幅之類的) ![](https://i.imgur.com/KqmygUW.png) - ### header, down, bottom 三種一起出現的機會非常低 [![](https://i.imgur.com/ehryFof.png)](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>