Snowpark をシュシュっと始める(Snowtireを使って)

# この記事は何？

Snowflake のSparkっぽい機能 Snowpark を Notebook で使えるようにするところまで一気に書いた記事です
参考 Snowtire：https://github.com/zoharsan/snowtire_v2

# 早速Notebookを起動するところまで

まずは Snowtire(v2) を clone します

```zsh
% git clone git@github.com:zoharsan/snowtire_v2.git
% cd snowtire_v2ｖ
```

次に build します

```
% docker build --pull -t snowtire .
```

そして run します(nameは適当につけてください)

```
% docker run -p 8888:8888 --name spare-0 snowtire:latest
(省略)
[C 12:19:02.007 NotebookApp] 
    
    To access the notebook, open this file in a browser:
        file:///home/jovyan/.local/share/jupyter/runtime/nbserver-16-open.html
    Or copy and paste one of these URLs:
        http://ef149ca5921e:8888/?token=hogehogehogehogehogehogehogehogehogehoge
     or http://127.0.0.1:8888/?token=hogehogehogehogehogehogehogehogehogehoge
```

最後に先程表示されたURLをブラウザなどで開きます

```
open http://127.0.0.1:8888/?token=hogehogehogehogehogehogehogehogehogehoge
```

開くとこんな感じです↓
![Home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75613/24204ef6-ea01-b6bc-3d03-c9452726fdb1.png)

# Snowparkを動かしましょう！

New から Scala を選んで、 Scala 用の空の Notebook を作成します
Notebookの名前は何でも良いです。

Snowpark 用に環境を設定していきます

参考： Snowpark用Jupyterノートブックの設定 https://docs.snowflake.com/ja/developer-guide/snowpark/quickstart-jupyter.html

## Notebook の前準備


最初のセルでは Snowpark が依存するライブラリの Maven リポジトリを使用するようにリポジトリを追加します

```
import sys.process._
val osgeoRepo = coursierapi.MavenRepository.of("https://repo.osgeo.org/repository/release")
interp.repositories() ++= Seq(osgeoRepo)
```

2つ目のセルで replClassPath を設定します
今回は `/home/jovyan/work/repl` にしてますが、好きなところに設定してください

```
import sys.process._
val replClassPath = "/home/jovyan/work/repl" // e.g. /home/myusername/replClasses
s"mkdir -p $replClassPath" !
```

3つ目のセルで replClassPath にクラスを生成するように設定して、依存関係に含めるようにします

```
interp.configureCompiler(_.settings.outputDirs.setSingleOutput(replClassPath))
interp.configureCompiler(_.settings.Yreplclassbased)
interp.load.cp(os.Path(replClassPath))
```

これでこの Notebook で Snowpark を使う前準備ができました

## Snowpark インストールして実行

下記のような感じで Snowpark 用のセッションを作成できます

```
// Import the Snowpark library from Maven.
import $ivy.`com.snowflake:snowpark:0.8.0`

import com.snowflake.snowpark._
import com.snowflake.snowpark.functions._

val session = Session.builder.configs(Map(
    "URL" -> "https://<account_identifier>.snowflakecomputing.com",
    "USER" -> "<username>",
    "PRIVATEKEY" -> "<private rsa key copied from your private key file>",
    "ROLE" -> "<role_name>",
    "WAREHOUSE" -> "<warehouse_name>",
    "DB" -> "<database_name>",
    "SCHEMA" -> "<schema_name>"
)).create

// Add the directory for REPL classes that you created earlier.
session.addDependency(replClassPath)
```

セッションができたら下記のように Notebook で書いた UDF が Snowflake 側で動くように依存ライブラリとして、 Ammonite を設定します。
これをしないとローカルの Notebook では Ammonite で動くコードを書いたけど、 Snowflake 側は通常のインタプリタのママになって、動かないUDFを作ってしまう可能性が出てしまうと思います

```
def addClass(session: Session, className: String): String = {
  var cls1 = Class.forName(className)
  val resourceName = "/" + cls1.getName().replace(".", "/") + ".class"
  val url = cls1.getResource(resourceName)
  val path = url.getPath().split(":").last.split("!").head
  session.addDependency(path)
  path
}
addClass(session, "ammonite.repl.ReplBridge$")
addClass(session, "ammonite.interp.api.APIHolder")
addClass(session, "pprint.TPrintColors")
```

もう Snowpark を動かせているんですが、念の為 UDF の動作確認をしてみましょう。

```
class UDFCode extends Serializable {
  val appendLastNameFunc = (s: String) => {
    s"$s Johnson"
  }
}
val appendLastNameUdf = udf((new UDFCode).appendLastNameFunc)
val df = session.sql("select 'Raymond' NAME")

df.withColumn("Full Name", appendLastNameUdf(col("NAME"))).show()
```

上記を実行すると下記のように表示されれば成功です。

```
-----------------------------
|"NAME"   |"Full Name"      |
-----------------------------
|Raymond  |Raymond Johnson  |
-----------------------------
```
![Snowpark_-_Jupyter_Notebook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75613/982b7224-f9e8-fdc9-69ef-25c1d79b927d.png)


# まとめ

こんな感じならだれでも Snowpark をサクッと始められそうですね！

そういえば、2021年10月5日に Snowflake の開発者向けグローバルイベント BUILD の日本ローカルイベントとして BUILD.local でお話します！
もしよければご視聴ください〜
https://usergroups.snowflake.com/events/details/snowflake-japan-presents-buildlocal-japan-snowparkdexi-ufei-gou-zao-deta-playing-with-unstructured-data-using-snowpark/