Jupyter LabおよびExtensionの紹介

Jupyter LabおよびExtensionの紹介

この記事はPyData Osaka Meetup #12の発表のために執筆しました。 ※2020/2/16 スライドへのリンクを追加

In [1]:
from IPython.display import IFrame
IFrame("https://www.hiromasa.info/slide/17.slides.html", "100%", "450px")
Out[1]:

自己紹介

  • 大橋(@wrist)
  • PyData Osakaオーガナイザーの一味
  • メーカー勤務(音響信号処理屋)
  • 近況: バタフライキーボードのbが壊れた

本日の実行環境

  • Docker上で動作
  • docker pull wrist/jupyterlab-custom:latest

本日の内容

  • Jupyter Labの簡単な歴史
  • Jupyter Lab単体機能の紹介
  • Extensionの紹介

Jupyter Labの簡単な歴史

Jupyter lab単体機能の紹介

個人的にJupyter Notebookに求めるもの

  • markdown/ipynbでのブログ執筆
  • ipynbのスライドへの変換
  • vimキーバインド

キーバインドの設定

  • デフォルトで用意
    • Settings -> Text Editor Key Map
    • Sublime Text, vim, emacs

vimキーバインド

  • markdown編集などのみに適用
    • cell編集でvimキーバインドが使いたい場合はExtensionが必要
  • chrome/safariで使うのが無難?
    • firefoxだとescが効かない

ショートカット

  • ipynbではjupyter notebookのショートカットがそのまま使える
    • 移動 j,k
    • 選択 J,K
    • 挿入 a,b
    • コピペ c,x,v
    • セルタイプ変更 m, y
    • ドキュメント表示 shift+tab
In [1]:
# sumにカーソルをあてて`shift+tab`
y = sum([1, 2, 3])
y
Out[1]:
6
In [2]:
import scipy as sp
import scipy.signal as sg

labの機能のショートカット(一部)

  • コマンドパレット
    • shift+command+c
  • タブの移動
    • shift+ctrl+]
  • サイドバーの開閉
    • command+B

slide type変更のショートカットがないのが辛い

Drag&Dropによるセル編集

  • ipynb間でも可能

画像のペーストによる挿入

  • セルにはクリップボード上の画像をcommand+vで挿入可能
  • win+shift+sshift+ctrl+command+4で選択してキャプチャした矩形画像を挿入

image.png

プレビュー関連

Markdownのプレビュー
  • markdownファイルを右クリック
    • Show Markdown Previewを選択

リッチな補完

  • 補完が見やすい

image.png

ipynbのSlideへの変換

  • 各セルにサイドバー -> スパナアイコン -> Slide Typeを設定
  • File -> Export Notebook As... -> Reveal.jsでスライド生成
  • RISEはまだ使えない模様
    • リアルタイム修正ができない

image.png

ipynbへのメタデータの付与

  • スパナアイコン -> Advanced Tools -> Notebook Metadataで付与可能

Extensionの紹介

Extensionの種類

  • lab extension
    • フロントエンド側で動作するExtension
    • jupyter labextension install ...
  • server extension
    • サーバー側で動作するExtension
    • pip install jupyterlab_git
    • jupyter serverextension enable --py jupyterlab_git

Extension情報

Extension Manger

  • GUIでインストールが可能
  • コマンドパレットからEnable Extension Managerを実行
  • サイドバーからExtensionのインストールが可能に

@jupyter/toc

  • 目次をサイドバーに表示可能
  • アウトラインが分かりやすくなる

image.png

インストール方法

https://github.com/jupyterlab/jupyterlab-toc

jupyter labextension install @jupyter/toc

@jupyter/git

  • サイドバーからgit操作が可能
  • nbdimeによる差分表示
サイドバー
  • GUI操作でgit関連操作が可能

image.png

差分表示
  • 一番右の2つのアイコン
    • チェックポイントからの差分
    • HEADからの差分

image.png

インストール方法

https://github.com/jupyterlab/jupyterlab-git

pip install jupyterlab_git
jupyter serverextension enable --py jupyterlab_git
jupyter labextension install @jupyterlab/git
jupyter lab build

jupyterlab-vim

  • cellの中でもvimキーバインドが使える
    • 割と使い勝手が変わるので好みによる
  • セルからの脱出
    • shift+ctrl+esc
  • セルの確定
    • ctrl+enter(エクステンションに関係なく使用可能)
コロンをセルの中で押した場合の様子

image.png

インストール方法

https://github.com/jwkvam/jupyterlab-vim

jupyter labextension install jupyterlab_vim

@lckr/jupyterlab_variableinspector

  • 変数の一覧表示を実現
    • numpyなどにも対応
    • matrix表示可能
    • _に辞書を格納してるっぽい
      • 直前の出力が参照できなくなる

インストール方法

https://github.com/lckr/jupyterlab-variableInspector

jupyter labextension install @lckr/jupyterlab_variableinspector
In [6]:
1+1
Out[6]:
2
In [7]:
_
Out[7]:
'[{"varName": "a", "varType": "ndarray", "varSize": "1600", "varShape": "10 x 20", "varContent": "array([[-1.86952991e+00, -4.47590288e-01,  1.34226809e+00,\\n         3.89567167e-01,  2.11721934e-01, -1.11331027e-01,\\n        -1.58066888e+00,  4.8026 ...", "isMatrix": true}, {"varName": "x", "varType": "int", "varSize": "28", "varShape": "", "varContent": "1", "isMatrix": false}, {"varName": "y", "varType": "int", "varSize": "28", "varShape": "", "varContent": "6", "isMatrix": false}]'

使用方法

  • 右クリックメニュー
    • Open Variable Inspectorを選択

image.png

In [5]:
import numpy as np

x = 1
a = np.random.randn(10, 20)
変数一覧表示

image.png

ndarrayのmatrix表示

image.png

@ryantam626/jupyterlab_code_formatter

  • 各種コード整形ライブラリをセルに適用
    • コマンドパレットやipynb上部アイコンから使用
コマンドパレットから使用

image.png

アイコンから使用
  • 右から3番目のアイコン

image.png

インストール方法

https://github.com/ryantam626/jupyterlab_code_formatter

jupyter labextension install @lckr/jupyterlab_variableinspector

環境構築用のDockerfileの例

FROM jupyter/scipy-notebook
MAINTAINER Hiromasa OHASHI <stoicheia1986@gmail.com>

RUN pip install jupyterlab_git jupyterlab_code_formatter autopep8 black
RUN jupyter serverextension enable --py jupyterlab_git
RUN jupyter serverextension enable --py jupyterlab_code_formatter

RUN jupyter labextension install \
  @jupyterlab/toc @jupyterlab/git \
  @lckr/jupyterlab_variableinspector \
  @ryantam626/jupyterlab_code_formatter

RUN jupyter lab build

まとめ

  • Jupyter Labの基本的な機能とExtensionを紹介
  • 他にも色々便利な機能などあると思いますのでご意見ください

nikolaの記事をjupyter labで書く

nikolaの記事をjupyter labで書く

この記事はPython その2 Advent Calendarの22日目の記事です。 当日休日出勤になってしまっていたので遅刻してしまいました。すいません。

nikolaはipynbファイルでブログが書けるstatic site generatorの一種です。 nikolaについては過去に記事を書いていますのでご覧ください。 https://www.hiromasa.info/categories/nikola/

jupyter labの実行環境

ここではjupyter公式のscipy-notebookのdockerイメージを立ち上げてjupyter labを動かしています。ゆくゆくはこれにnikolaのブログ構築環境を追加したイメージを作成したいと思っています。 実行する場合は下記のような感じでブログ本体のあるディレクトリを/mnt/blogにマッピングしてローカルホストに対してポート8888でアクセスします。

docker run -ti -v /path/to/blog:/mnt/blog -p 8888:8888 jupyter/scipy-notebook /bin/bash

jupyter labでのMetadataの設定

Nikolaではこの記事に書いたように.ipynbファイルを公開する場合はblog用のメタデータを.ipynbファイルに付与する必要があります。 Metadataの設定はhttps://github.com/jupyterlab/jupyterlab/issues/1308 のissueで議論され、https://github.com/jupyterlab/jupyterlab/pull/5968 のプルリクエストで追加するためのUIが4月ごろに追加されています。

メタデータを付与するためには、一番左側のアイコンの並んでいるカラムからスパナアイコンを選択肢、Advanced Toolsの中のNotebook Metadataを編集すれば良いです。この記事では下記の様な感じにしています。

"nikola": {
        "tags": "python,docker,nikola,jupyterlab",
        "title": "nikolaの記事をjupyter labで書く",
        "date": "2019-12-22 23:00:00 UTC+09:00",
        "type": "text",
        "slug": "16",
        "category": "",
        "link": "",
        "description": ""
    }

image.png

画像のDrag & Dropおよびペースト

このプルリクエストによれば、

  • ファイルブラウザからセルへのドラッグアンドドロップによるファイルの保存
  • セルへの画像のペースト
  • セルのソースをattachmentを加えるように変更する
  • セルのattatchmentがセルの出力のどこからも参照されていない場合にはattachmentを削除する

が既に実現されているようです。 上記には記述がありませんが、そもそも(finderなどから)ファイルブラウザへのドラッグアンドドロップによる保存は可能ですので、そこから更にセルにドラッグアンドドロップすることも可能ですし、osxならshift+ctrl+command+4で範囲選択した内容をcommand+vで挿入できるので便利です。挿入した画像はbase64エンコードされてipynbに埋め込まれます。注意が必要なのは各セルに対してattachmentを複数埋め込むと後から貼り付けたもので上書きされてしまう点です。各セルにcommand+vで貼る画像は今の所一つにとどめておいた方が無難なようです。

extensionの導入

shift+command+cでコマンドパレットを表示し、Enable Extension Managerを選択・実行してEnableにすると左側のアイコンが並んでいるカラムにextention managerが表示されます。これによりjupyter lab上からextensionがインストールできるようになります。コマンドライン上でjupyter labextension installを実行するのと同等の操作が実行できるのだと思います。ここでは試しにtocと打ってみて目次を表示するextensionである@jupyterlab/tocをインストールしてみます。

image.png

インストールを実行したあとにブラウザのタブをリロードすると、ビルドするかを尋ねられるのでビルドを実行後、ビルドが完了するとreloadを求められました。reload後、左側のアイコンのカラムにTOCのアイコンが出現していました。

更にgitのextensionである@jupyter/gitをインストールしてみます。 インストールを実行すると、下記のようにこのextensionを使用する前に対応したserver extensionであるjupyter-gitをインストールしておく必要があると言われます。 image.png

自分はserver extensionを入れる前にOKを押してしまいましたが、先程と同じようにブラウザのタブをリロードするとextensionのビルドが求められました。しばらくするとBuildが完了した旨が表示されます。

server extensionを入れるにはpipでjupyterlab_gitを入れた後にjupyter serverextension enable --py jupyterlab_gitを実行すれば良いようです。

In [13]:
! pip install jupyterlab_git
Collecting jupyterlab_git
  Downloading https://files.pythonhosted.org/packages/24/9b/ce8a9166a0ed945aada0703d0ebae3e98b539b45db0188e571c1d384e68d/jupyterlab_git-0.9.0-py3-none-any.whl (144kB)
     |████████████████████████████████| 153kB 641kB/s eta 0:00:01
Requirement already satisfied: pexpect in /opt/conda/lib/python3.7/site-packages (from jupyterlab_git) (4.7.0)
Requirement already satisfied: notebook in /opt/conda/lib/python3.7/site-packages (from jupyterlab_git) (6.0.0)
Collecting nbdime>=1.1.0
  Downloading https://files.pythonhosted.org/packages/0f/3f/668922f04fa6848437d8486c495ceea2fbe2b011e1084cb49a792c4bec31/nbdime-1.1.0-py2.py3-none-any.whl (4.3MB)
     |████████████████████████████████| 4.3MB 294kB/s eta 0:00:01
Requirement already satisfied: ptyprocess>=0.5 in /opt/conda/lib/python3.7/site-packages (from pexpect->jupyterlab_git) (0.6.0)
Requirement already satisfied: jupyter-client>=5.3.1 in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (5.3.3)
Requirement already satisfied: ipykernel in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (5.1.3)
Requirement already satisfied: prometheus-client in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (0.7.1)
Requirement already satisfied: traitlets>=4.2.1 in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (4.3.3)
Requirement already satisfied: tornado>=5.0 in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (6.0.3)
Requirement already satisfied: Send2Trash in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (1.5.0)
Requirement already satisfied: terminado>=0.8.1 in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (0.8.3)
Requirement already satisfied: jinja2 in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (2.10.3)
Requirement already satisfied: pyzmq>=17 in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (18.1.1)
Requirement already satisfied: nbformat in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (4.4.0)
Requirement already satisfied: jupyter-core>=4.4.0 in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (4.6.1)
Requirement already satisfied: nbconvert in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (5.6.1)
Requirement already satisfied: ipython-genutils in /opt/conda/lib/python3.7/site-packages (from notebook->jupyterlab_git) (0.2.0)
Requirement already satisfied: six in /opt/conda/lib/python3.7/site-packages (from nbdime>=1.1.0->jupyterlab_git) (1.13.0)
Requirement already satisfied: pygments in /opt/conda/lib/python3.7/site-packages (from nbdime>=1.1.0->jupyterlab_git) (2.5.2)
Requirement already satisfied: requests in /opt/conda/lib/python3.7/site-packages (from nbdime>=1.1.0->jupyterlab_git) (2.22.0)
Collecting colorama
  Downloading https://files.pythonhosted.org/packages/c9/dc/45cdef1b4d119eb96316b3117e6d5708a08029992b2fee2c143c7a0a5cc5/colorama-0.4.3-py2.py3-none-any.whl
Collecting GitPython!=2.1.4,!=2.1.5,!=2.1.6
  Downloading https://files.pythonhosted.org/packages/20/8c/4543981439d23c4ff65b2e62dddd767ebc84a8e664a9b67e840d1e2730d3/GitPython-3.0.5-py3-none-any.whl (455kB)
     |████████████████████████████████| 460kB 801kB/s eta 0:00:01
Requirement already satisfied: python-dateutil>=2.1 in /opt/conda/lib/python3.7/site-packages (from jupyter-client>=5.3.1->notebook->jupyterlab_git) (2.8.1)
Requirement already satisfied: ipython>=5.0.0 in /opt/conda/lib/python3.7/site-packages (from ipykernel->notebook->jupyterlab_git) (7.10.1)
Requirement already satisfied: decorator in /opt/conda/lib/python3.7/site-packages (from traitlets>=4.2.1->notebook->jupyterlab_git) (4.4.1)
Requirement already satisfied: MarkupSafe>=0.23 in /opt/conda/lib/python3.7/site-packages (from jinja2->notebook->jupyterlab_git) (1.1.1)
Requirement already satisfied: jsonschema!=2.5.0,>=2.4 in /opt/conda/lib/python3.7/site-packages (from nbformat->notebook->jupyterlab_git) (3.2.0)
Requirement already satisfied: bleach in /opt/conda/lib/python3.7/site-packages (from nbconvert->notebook->jupyterlab_git) (3.1.0)
Requirement already satisfied: entrypoints>=0.2.2 in /opt/conda/lib/python3.7/site-packages (from nbconvert->notebook->jupyterlab_git) (0.3)
Requirement already satisfied: defusedxml in /opt/conda/lib/python3.7/site-packages (from nbconvert->notebook->jupyterlab_git) (0.6.0)
Requirement already satisfied: pandocfilters>=1.4.1 in /opt/conda/lib/python3.7/site-packages (from nbconvert->notebook->jupyterlab_git) (1.4.2)
Requirement already satisfied: mistune<2,>=0.8.1 in /opt/conda/lib/python3.7/site-packages (from nbconvert->notebook->jupyterlab_git) (0.8.4)
Requirement already satisfied: testpath in /opt/conda/lib/python3.7/site-packages (from nbconvert->notebook->jupyterlab_git) (0.4.4)
Requirement already satisfied: idna<2.9,>=2.5 in /opt/conda/lib/python3.7/site-packages (from requests->nbdime>=1.1.0->jupyterlab_git) (2.8)
Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/lib/python3.7/site-packages (from requests->nbdime>=1.1.0->jupyterlab_git) (2019.11.28)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /opt/conda/lib/python3.7/site-packages (from requests->nbdime>=1.1.0->jupyterlab_git) (1.25.7)
Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /opt/conda/lib/python3.7/site-packages (from requests->nbdime>=1.1.0->jupyterlab_git) (3.0.4)
Collecting gitdb2>=2.0.0
  Downloading https://files.pythonhosted.org/packages/03/6c/99296f89bad2ef85626e1df9f677acbee8885bb043ad82ad3ed4746d2325/gitdb2-2.0.6-py2.py3-none-any.whl (63kB)
     |████████████████████████████████| 71kB 1.7MB/s eta 0:00:01
Requirement already satisfied: backcall in /opt/conda/lib/python3.7/site-packages (from ipython>=5.0.0->ipykernel->notebook->jupyterlab_git) (0.1.0)
Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /opt/conda/lib/python3.7/site-packages (from ipython>=5.0.0->ipykernel->notebook->jupyterlab_git) (3.0.2)
Requirement already satisfied: pickleshare in /opt/conda/lib/python3.7/site-packages (from ipython>=5.0.0->ipykernel->notebook->jupyterlab_git) (0.7.5)
Requirement already satisfied: setuptools>=18.5 in /opt/conda/lib/python3.7/site-packages (from ipython>=5.0.0->ipykernel->notebook->jupyterlab_git) (42.0.2.post20191201)
Requirement already satisfied: jedi>=0.10 in /opt/conda/lib/python3.7/site-packages (from ipython>=5.0.0->ipykernel->notebook->jupyterlab_git) (0.15.1)
Requirement already satisfied: pyrsistent>=0.14.0 in /opt/conda/lib/python3.7/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat->notebook->jupyterlab_git) (0.15.6)
Requirement already satisfied: attrs>=17.4.0 in /opt/conda/lib/python3.7/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat->notebook->jupyterlab_git) (19.3.0)
Requirement already satisfied: importlib-metadata; python_version < "3.8" in /opt/conda/lib/python3.7/site-packages (from jsonschema!=2.5.0,>=2.4->nbformat->notebook->jupyterlab_git) (1.1.0)
Requirement already satisfied: webencodings in /opt/conda/lib/python3.7/site-packages (from bleach->nbconvert->notebook->jupyterlab_git) (0.5.1)
Collecting smmap2>=2.0.0
  Downloading https://files.pythonhosted.org/packages/55/d2/866d45e3a121ee15a1dc013824d58072fd5c7799c9c34d01378eb262ca8f/smmap2-2.0.5-py2.py3-none-any.whl
Requirement already satisfied: wcwidth in /opt/conda/lib/python3.7/site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->ipython>=5.0.0->ipykernel->notebook->jupyterlab_git) (0.1.7)
Requirement already satisfied: parso>=0.5.0 in /opt/conda/lib/python3.7/site-packages (from jedi>=0.10->ipython>=5.0.0->ipykernel->notebook->jupyterlab_git) (0.5.1)
Requirement already satisfied: zipp>=0.5 in /opt/conda/lib/python3.7/site-packages (from importlib-metadata; python_version < "3.8"->jsonschema!=2.5.0,>=2.4->nbformat->notebook->jupyterlab_git) (0.6.0)
Requirement already satisfied: more-itertools in /opt/conda/lib/python3.7/site-packages (from zipp>=0.5->importlib-metadata; python_version < "3.8"->jsonschema!=2.5.0,>=2.4->nbformat->notebook->jupyterlab_git) (7.2.0)
Installing collected packages: colorama, smmap2, gitdb2, GitPython, nbdime, jupyterlab-git
Successfully installed GitPython-3.0.5 colorama-0.4.3 gitdb2-2.0.6 jupyterlab-git-0.9.0 nbdime-1.1.0 smmap2-2.0.5
In [14]:
! jupyter serverextension enable --py jupyterlab_git
Enabling: jupyterlab_git
- Writing config: /home/jovyan/.jupyter
    - Validating...
      jupyterlab_git  OK

上記を実行した後にブラウザのタブを再実行したところnbdime-jupyterlabのビルドがダイアログが表示され要求されたため実行しました。 しかしここまでを実行したところ、左側のアイコンが並んでいるカラムにgitのアイコンが表示されるようにはなりましたが、ローカルのリポジトリを読み込んでくれる気配がありませんのでこのあたりについては要調査の上で追記したいと思います。

2020/1/13追記

  • 後日確認したところjupyter lab上でgitのextensionをインストールする前にjupyter serverextension enable --py jupyterlab_gitを実行しておくと、自動的にjupyter labのextensionもインストールされていました
  • 事前にコマンドラインからビルドを実行しておく場合はjupyter lab buildで行けるようです
  • ローカルのリポジトリを読み込まない問題はリポジトリのページを確認したところTroubleShootingの欄のIssue: the Git panel does not recognize that you are in a Git repository.として記載がありましたが原因はjupyter serverextension enable --py jupyterlab_gitを実行した後に、コマンドラインまたはjupyter lab上の表示からビルドを行った上でjupyter labを立ち上げていないことでした。つまり稼働中にserverextensionをenableしてからビルドを行うのではなく、稼働前にビルドを実行しておく必要がありました。上記を踏まえた上でjupyter labを再起動したら下記のような感じのインタフェースが使えるようになりました。

image.png

ブログのビルド

ここではブログのビルド自体はローカル環境(docker上ではない)で実行しています。

$ nikola build
$ nikola serve -b

上記を実行するとビルドを実行した上でローカルサーバを立ち上げてくれ、-bオプションによって自動的にブラウザのタブが開きます。内容に問題ないことを確認したら、あとはサーバーにプッシュしておしまいです。

まとめ

jupyter lab上でブログを執筆する環境構築について記しました。