JupyterのPythonラッパーKernel(Rust)を作ってみた

この記事は[jupyter notebook Advent Calender 2016](http://qiita.com/advent-calendar/2016/jupyter) 21日目の記事です。

# はじめに
近頃、[君の名は。](http://www.kiminona.com/index.html)と[Rust](https://www.rust-lang.org/en-US/)にはまっています。(君の名は。は本記事には1ミリも関係がありません。)

Rustは最近始めたのですが、かなり面白いです。
勉強していく中で思ったこととかをNotebookとして残していけたらいいな、と思いましたが
残念ながらRust言語のKernelは見つかりません。

ということで、Rust用のJupyter Kernelを作成してみました。

# やったこと
以下2つの作業をすると新しいKernelが使えるようになるようです。
1.Kernelの作成
2.Kernelspecへの追加

## 1.Kernelの作成

公式の[Making kernels for Jupyter](https://jupyter-client.readthedocs.io/en/latest/kernels.html#kernels)を見ると、以下の様にあります。
>There are two options for writing a kernel:
>
>1.You can reuse the IPython kernel machinery to handle the communications, and just describe how to execute your code. This is much simpler if the target language can be driven from Python. See [Making simple Python wrapper kernels](https://jupyter-client.readthedocs.io/en/latest/wrapperkernels.html) for details.
>2.You can implement the kernel machinery in your target language. This is more work initially, but the people using your kernel might be more likely to contribute to it if it’s in the language they know.

なるほど。わからん。
とりあえず、pythonから呼び出す形で良ければより簡単に作れるよってことだと理解して
1番の「[Making simple Python wrapper kernels](https://jupyter-client.readthedocs.io/en/latest/wrapperkernels.html)」の方法で作成していきます。

どうやら、ipykernel.kernelbase.Kernelのsubclassとして
MyKernelを定義して、実行された場合に呼ばれるメソッド等を作成してくとできる見たいですね。
much simplerは本当だった！すごいシンプル！！

[C言語のKernel実装](https://github.com/brendan-rius/jupyter-c-kernel)がまさにこの方法かつ、MITライセンスで公開してくれているので、
Rust用に一部変えるとすぐにできそうです。
\# brendan-riusさん、ありがとうございます。

## 2.kernelspec への追加

公式の[Kernel Spec](https://jupyter-client.readthedocs.io/en/latest/kernels.html#kernel-specs)参照です。

新しい言語Kernelを追加するにはkernelspecへの追加が必要みたいです。
jupyterのkernelspecコマンドで操作ができます。

```
# jupyter kernelspec help

Manage Jupyter kernel specifications.

Subcommands
-----------
Subcommands are launched as `jupyter kernelspec cmd [args]`. For information on
using subcommand 'cmd', do: `jupyter kernelspec cmd -h`.

install-self
    [DEPRECATED] Install the IPython kernel spec directory for this Python.
list
    List installed kernel specifications.
install
    Install a kernel specification directory.
remove
    Remove one or more Jupyter kernelspecs by name.
uninstall
    Alias for remove
```

helpの通り、installでkernelspecのインストールができます。
(といっても、各OSごとに定められたディレクトリにkernel.jsonごとディレクトリを取り込んでいるだけのようです。)

実際にinstallします。
以下のようなkernel.jsonを作成し

```json:rust_spec/kernel.json
{
  "argv": [ //Kernel起動時に実行するコマンドを定義する
    "python",
    "-m",
    "jupyter_rust_kernel",
    "-f",
    "{connection_file}"
  ],
  "display_name": "Rust",
  "language": "rust"
}
```
installの実行。

```
# jupyter kernelspec install rust_spec
[InstallKernelSpec] Installed kernelspec rust_spec in /usr/local/share/jupyter/kernels/rust_spec
```

lsitを見てみると、

```
# jupyter kernelspec list
Available kernels:
  python2      /usr/local/lib/python2.7/dist-packages/ipykernel/resources
  rust_spec    /usr/local/share/jupyter/kernels/rust_spec
```
認識されたことが確認できました。


# 完成

そんなこんなで完成しました。
全体はgithubにあげたので[こちら](https://github.com/moriiiii/jupyter-rust-kernel)を参照してください。

Rustのtopページにあるコードが動かせました。
![rust_notebook.PNG](https://qiita-image-store.s3.amazonaws.com/0/76107/e78c4864-4e4c-a39d-c199-844d47b3fd64.png)

# Kernelの詳細

今回、RustKernelを~~作成~~一部修正しましたが、
行っていることは、ざっくり以下の3点です。

1. jupyterに記述され実行するコマンドを受け取りファイルに出力(do_execute)
2. rustcデコンパイルして実行ファイル
3. shutdown時には作成したファイルを一括削除(do_shutdown)

なので、どの言語も同じ方針で作ることができそうです。
しかし、interactiveなKernelを作ることはできないと思うので、
interactiveなKernelはもう一方のKernelの作り方で作成する必要があるんでしょうか。
(未だよくわかってない。。。)

ただ、RustKernelも
do_complete使って、補完させたりなど、まだまだ改良の余地はありそうなので、
引き続きいじっていこうと思います。

# 終わりに

Jupyterの勢い、すごいですね！
私がJupyterを知ったのは、今年の5月に先輩に[この本(IPythonデータサイエンスクックブック)](https://www.amazon.co.jp/IPython%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9%E3%82%AF%E3%83%83%E3%82%AF%E3%83%96%E3%83%83%E3%82%AF-_%E5%AF%BE%E8%A9%B1%E5%9E%8B%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%A8%E5%8F%AF%E8%A6%96%E5%8C%96%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%AC%E3%82%B7%E3%83%94%E9%9B%86-Cyrille-Rossant/dp/4873117488/ref=sr_1_1?ie=UTF8&qid=1482202926&sr=8-1&keywords=ipython+notebook)を教えてもらってでした。
何て面白そうなんだ、と思いすぐに本を買い、使い始めました。

IPythonから,Jupyter,JupyterLabへとどんどん便利になっていきますね。

さらに、皆さんが様々な便利な使い方等を書いてくれているので、
もっと勉強して最大限に活用していきたいです！

ここまで読んでいただき、ありがとうございました！！