こんにちは!日々のデータ分析やAI開発で、JupyterLabを相棒のように使い倒していますか?
「あともう一歩、ここに独自のデータプレビュー機能があったら…」
「毎回手動で実行している定型クエリを、サイドバーのボタン一発で呼び出せたら…」
そう思ったことはありませんか?世の中には便利な拡張機能が溢れていますが、本当に自分やチームの業務に特化した痒いところに手が届くツールは、自分で作るのが一番の近道です。
今回は、JupyterLabの内部構造を紐解きながら、自分だけの「マジックコマンド」と「サイドバーUI」を自作する拡張機能開発の世界へあなたを優しく案内します。これをマスターすれば、毎日のコーディングや実験プロセスが劇的に楽になりますよ。さあ、一緒にエンジニアとしての新しい扉を開きましょう!
—
なぜJupyterLabの拡張機能を作るのか?(アーキテクトの視点)
JupyterLabは、単なる「ブラウザで動くコードエディタ」ではありません。その実態は、TypeScriptとモジュール化されたプラグインアーキテクチャ(LuminoJS)によって精密に組み上げられた、モダンなWebアプリケーションプラットフォームです。
既存のPythonスクリプトやシェルスクリプトで自動化するのも良いですが、JupyterLabのUI(サイドバーやコマンドパレット)と密結合した拡張機能を作ると、次のような圧倒的なメリットが生まれます。
1. コンテキストの維持: ノートブックからタブを切り替えることなく、手元でカスタムUIやデータビジュアライザを操作できる。
2. マジックコマンドによる拡張: `%my_command` のように書くだけで、複雑なAPI連携や前処理をJupyterのセルから直接呼び出せる。
3. チームへの資産共有: 組織固有のワークフローをパッケージ化して配布すれば、チーム全体の開発スピードが跳ね上がる。
それでは早速、この強力なエコシステムに参加するための開発環境を構築していきましょう。
—
1. 開発環境の構築と心構え
JupyterLabの拡張機能開発には、Node.js(TypeScriptのコンパイルとJupyterLabのビルドシステム `jlpm` のため)と、Pythonの仮想環境が必要です。
まずは、開発用のクリーンな環境を整えましょう。
開発用パッケージのインストールと確認
ターミナルを開き、以下のコマンドを実行します。ここでは拡張機能の雛形を生成する公式のCookiecutterテンプレートを利用します。
Node.jsとPython(>=3.8)がインストールされていることを前提に、
JupyterLabの拡張機能開発に必要なCookiecutterとTypeScript関連ツールを導入します
pip install cookiecutter jupyterlab>=4.0.0
環境が整ったら、公式のTypeScript用テンプレートからプロジェクトの骨組みを作成します。
対話形式で拡張機能のメタデータ(名前や作者名など)を聞かれるため、
お好みの名前(例: jupyterlab-custom-helper)を入力します
cookiecutter https://github.com/jupyterlab/extension-cookiecutter-ts
生成されたディレクトリ(例: `jupyterlab-custom-helper`)に移動し、依存関係をインストールして開発ビルドを有効化します。
cd jupyterlab-custom-helper
JupyterLab同梱のパッケージマネージャ(yarnのラッパー)で依存関係をインストール
jlpm install
—
2. 拡張機能の心臓部:TypeScriptとLuminoの基本
生成されたプロジェクトの中を見てみましょう。`src/index.ts` がこの拡張機能のすべての起点となります。
JupyterLabのUIを構築しているのは、LuminoJS(旧PhosphorJS)という強力なウィジェットライブラリです。ReactやVueに似ていますが、デスクトップアプリのような高度なドッキングレイアウトやコマンド管理をブラウザ上で実現するように設計されています。
それでは、実際にコードを書いて、「サイドバーへのUI追加」と「コマンドパレットへの登録」を実装していきましょう。
`src/index.ts` の実装解説
以下のコードは、左サイドバーにカスタムボタンを持つパネルを追加し、クリックされたらログを出力、同時にコマンドパレットにも登録するというものです。
import {
JupyterFrontEnd,
JupyterFrontEndPlugin
} from ‘@jupyterlab/application’;
import { ICommandPalette } from ‘@jupyterlab/apputils’;
import { Widget } from ‘@lumino/widgets’;
/
- 拡張機能のメインロジックを定義するクラス
- Luminoの Widget を継承して独自のDOM構造を持つパネルを作成します
/
class CustomSidebarWidget extends Widget {
constructor() {
super();
this.addClass(‘jp-CustomSidebarPanel’);
this.id = ‘custom-sidebar-helper’;
this.title.label = ‘カスタム助手’;
this.title.iconClass = ‘fa fa-rocket’; // アイコンの指定
// サイドバー内に表示するHTML要素を構築
const content = document.createElement(‘div’);
content.style.padding = ’12px’;
content.innerHTML = `
業務効率化パネル
このパネルから定型処理を呼び出せます。
`;
// ボタンをクリックしたときのインタラクションを定義
const button = content.querySelector(‘#custom-action-btn’);
if (button) {
button.addEventListener(‘click’, () => {
console.log(‘JupyterLab Custom Helper: ボタンがクリックされました!’);
alert(‘カスタム処理が正常にトリガーされました。’);
});
}
this.node.appendChild(content);
}
}
/
- JupyterLabにプラグインとして登録するオブジェクト
/
const plugin: JupyterFrontEndPlugin
id: ‘jupyterlab-custom-helper:plugin’,
autoStart: true,
requires: [ICommandPalette],
activate: (app: JupyterFrontEnd, palette: ICommandPalette) => {
console.log(‘JupyterLab extension jupyterlab-custom-helper is activated!’);
const { shell } = app;
// ウィジェットのインスタンスを生成
const widget = new CustomSidebarWidget();
// 1. JupyterLabの左サイドバー(left area)にウィジェットを追加
shell.add(widget, ‘left’, { rank: 1000 });
// 2. コマンドパレット(Ctrl+Shift+Cなどで開くメニュー)に独自のコマンドを登録
const commandId = ‘custom-helper:open-action’;
app.commands.addCommand(commandId, {
label: ‘カスタム助手:データ検証を実行’,
execute: () => {
console.log(‘コマンドパレットから実行されました’);
widget.node.focus();
}
});
palette.addItem({ command: commandId, category: ‘業務効率化ツール’ });
}
};
export default plugin;
ここがアーキテクトのこだわりポイント
- `ICommandPalette` のインジェクション: JupyterLabのプラグインシステムは依存性注入(DI)を採用しています。これにより、既存のコアコンポーネント(コマンドパレットやファイルブラウザなど)と安全に結合できます。
- Luminoのライフサイクル: `Widget` を継承することで、JupyterLabのレイアウトシステムが自動的にリサイズやDOMの破棄を管理してくれます。メモリリークを気にせず安心してUIを拡張できます。
—
3. マジックコマンド(Python側)の連携
UIだけでなく、Jupyterのセルから `%` や `%%` で呼び出せる「マジックコマンド」を自作して、Pythonバックエンドと連携させてみましょう。
JupyterLabの拡張機能は、TypeScript(フロントエンド)だけでなく、Pythonパッケージ(サーバー・内核の拡張)を同時に内包することができます。
プロジェクト内の `jupyterlab_custom_helper/` ディレクトリ(Python側)に、マジックコマンドを提供するモジュールを追加します。
`jupyterlab_custom_helper/magics.py` の実装
from IPython.core.magic import (
Magics, magics_class, line_magic
)
@magics_class
class CustomWorkflowMagics(Magics):
“””
データサイエンス業務を加速させる独自のマジックコマンド群
“””
@line_magic
def validate_data(self, line):
“””
使用例: %validate_data dataset.csv
指定されたデータセットの基本検証(欠損値チェックなど)を瞬時に実行します
“””
print(f”[カスタムマジック] 対象の検証を開始します: {line}”)
# ここに実際のデータ検証ロジック(pandasを使った処理など)を記述します
return “検証完了:異常値は検出されませんでした。”
def load_ipython_extension(ip):
“””
Jupyterのカーネルにこのマジックコマンドを登録するためのエントリーポイント
“””
ip.register_magics(CustomWorkflowMagics)
このPythonモジュールがJupyterのPythonカーネル起動時に自動読み込みされるよう、Python側の設定(`setup.py` または `pyproject.toml`)や、Jupyterのエントリーポイント(`jupyter_server_extension`)を設定します。
—
4. ローカルインストールと動作確認の儀式
コードを書いたら、いよいよJupyterLabにインストールしてその動きを確認します。開発中は、「開発モード(Development Mode)」でビルドするのが鉄則です。
ターミナルで拡張機能のルートディレクトリに戻り、以下のコマンドを実行してください。
開発モードとしてPythonパッケージをJupyterLabにインストール
pip install -e .
JupyterLabの拡張機能を開発用としてリンク(自動ビルド有効化)
jupyter labextension development . –watch
この `–watch` オプションをつけておくと、TypeScriptのコード(`src/index.ts`)を修正して保存するたびに、バックグラウンドで自動的にJupyterLabが再ビルドされます。開発効率が爆上がりする瞬間です。
動作確認の手順
1. 別ターミナル、または同じターミナルでJupyterLabを起動します。
jupyter lab
2. ブラウザでJupyterLabが立ち上がったら、次の点を確認してください:
- 左サイドバーに「ロケットアイコン(カスタム助手)」が表示されているか?
- アイコンをクリックして、自作の「データ検証を実行」ボタンが表示されるか?
- キーボードショートカット(`Ctrl + Shift + C` 等)でコマンドパレットを開き、「カスタム助手:データ検証を実行」がヒットするか?
これがスムーズに動いた瞬間、あなたは単なる「Jupyterの使用者」から「Jupyterエコシステムの創造者」へとステップアップしています!
—
おわりに:あなたの手で、開発環境を極限まで最適化しよう
今回は、JupyterLabのExtension開発における基礎、TypeScriptとLuminoJSを使ったサイドバーUIの構築、そして拡張機能のビルドとインストールまでの流れを解説しました。
最初は設定ファイルや不慣れなTypeScriptの型定義に戸惑うかもしれませんが、一度このパイプラインを理解してしまえば、日々の面倒な手作業を次々と自動化・UI化できるようになります。
「こんなツールがあったらチーム全員が助かるのに」——そのアイデアを形にする力は、もうあなたの手の中にあります。ぜひ、今日の業務の合間に試してみてくださいね。あなたの開発ライフがより快適で刺激的なものになることを、心から応援しています!