13
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Multi-Session Livebook Apps で GitHub と Slack を連携させる

Last updated at Posted at 2023-07-16

はじめに

Livebook 0.10.0 がリリースされましたね!

というわけで、公式の動画で Jose がやっていた Multi-Session Livebook Apps の構築をやってみました

基本的に公式動画に沿って実装するだけなので、英語が聞ける人は動画を見た方が良いです

また、公式動画では説明のためにわざと遠回りしていたところを端折って説明します

GitHub トークンや Slack トークンについては手順を紹介するので、そこで詰まった人には参考になると思います

Multi-Session Livebook Apps とは

Livebook Apps はノートブック上に実装した処理を、そのままアプリとしてリリースできる機能です

これによって、例えば以下のような画像識別AIアプリなどが簡単に構築できます

deploy_ai.gif

Livebook 0.9 の Livebook Apps は Single-Session だけでした

Single-Session では複数人がアプリにアクセスしたとき、全員で一つのセッションを共有します

セッションを共有することでチャットや共同編集など、チームでのコラボレーション機能を構築しやすくなっています

それに対して、新しい Multi-Session では、新しくアプリにアクセスしてきた人は、既存のセッションに参加するか、新しいセッションを作るか選択できます

別々のセッションを作った場合、それぞれに対する操作は完全に分離されます

例えば「CSV ファイルを読み込んで、指定した列の値をグラフ化する」という処理を Livebook Apps を実装したとき、セッション毎に別の CSV ファイル、列を指定することができます

アプリの実装内容

GitHub 上の指定したリポジトリーの情報を取得し、 Slack に取得結果を通知するアプリを作っていきます

slack.gif

実装したノートブックはこちら

事前準備

Livebook のインストール

@nako_sleep_9h さんの記事などを参考に Livebook をインストール、起動します

Livebook のバージョンは 0.10.0 以上が必須なので、既にインストールしている人は最新バージョンに更新してください

トークンの取得

GitHub と Slack の API を呼ぶため、それぞれの認証トークンが必要になります

GitHub のトークン

GitHub にログインします(アカウントがない場合はサインアップしてください)

GitHub の右上、自分をアイコンをクリックし、表示されるメニューから "Settings" を開きます

スクリーンショット 2023-07-16 8.31.00.png

"Settings" 画面で左メニューの一番下、 "Developer Settings" を開きます

スクリーンショット 2023-07-16 8.33.30.png

"Developer Settings" 画面の左メニュー "Personal access tokens" |> "Fine-grained personal access tokens" を開き、右上の "Generate new token"

スクリーンショット 2023-07-16 8.36.58.png

"Fine-grained personal access tokens" は従来の "Tokens (classic)" よりも、より詳細に権限管理できるようになっています

まだ Beta 版ではありますが、 GitHub のトークンを使う場合、今後はこちらを使いましょう

今回は特別な操作はしないため、 "Token name" に適当な値を入れたら他はそのまま "Generate token" をクリックします

スクリーンショット 2023-07-16 8.39.52.png

新しいトークンが発行され、値が表示されます

Slack のトークン

slack api にログインします(Slack のアカウントがない場合、サインアップして何らかのワークスペースを作ってください)

右上 "Your apps" を開き、 "Create your first app" をクリックします(初めての Slack アプリの場合)

スクリーンショット 2023-07-16 8.45.25.png

"Your Apps" 画面で "Create an App" をクリックします

スクリーンショット 2023-07-16 8.47.24.png

開いたモーダルで "From scratch" をクリックします

スクリーンショット 2023-07-16 8.47.33.png

"App Name" に適当な名前を入力し、使いたいワークスペースを選択します

"Create App" をクリックすると、 Slack アプリが作成されます

スクリーンショット 2023-07-16 8.47.49.png

左メニューから "OAuth & Permissions" を開きます

スクリーンショット 2023-07-16 8.52.11.png

下に移動し、 "Scopes" で上側の "Bot Token Scopes" に "Add an OAuth Scope" から "chat:write" の権限を追加します

スクリーンショット 2023-07-16 8.54.01.png

画面上に戻ると、 "Install to Workspace" が活性化しているので、クリックします

スクリーンショット 2023-07-16 8.56.09.png

"許可する" をクリックします

スクリーンショット 2023-07-16 8.56.52.png

Slack のトークンが表示されます

Slack でワークスペースを開くと、作成したアプリが追加されています

スクリーンショット 2023-07-16 8.58.28.png

Slack チャンネルの設定

お試し用のチャンネルを作ります

Slack で "チャンネルを追加する" |> "新しいチャンネルを作成する" をクリックします

スクリーンショット 2023-07-16 8.59.28.png

適当なチャンネル名を入力し "次へ" をクリックします

スクリーンショット 2023-07-16 8.59.59.png

何も変更せずに "作成" をクリックします

スクリーンショット 2023-07-16 9.00.12.png

新しいチャンネルが作成され、 "メンバーを追加する" というモーダルが開きますが、誰も追加しないので "後でする" をクリックします

スクリーンショット 2023-07-16 9.00.27.png

左メニューのチャンネル名を右クリックし、 "チャンネル詳細を表示する" をクリックします

スクリーンショット 2023-07-16 9.01.17.png

表示されるモーダルの "インテグレーション" タブを開き、 "App" の中の "アプリを追加する" をクリックします

スクリーンショット 2023-07-16 9.01.27.png

表示されるアプリ一覧から、自分が作成したアプリの右側 "追加" をクリックします

スクリーンショット 2023-07-16 9.01.40.png

これで準備は完了です

アプリの実装

セットアップ

新しいノートブックを開き、 Multi-Session Livebook App を構築してみましょう

以下のコードをセットアップセルに入力し、実行します

Mix.install([
  {:req, "~> 0.3"},
  {:kino, "~> 0.10"},
  {:kino_slack, "~> 0.1"}
])

必要なモジュールがノートブック上にインストールされます

シークレットの登録

GitHub と Slack のトークンをシークレットとして登録します

Livebook 左メニューの錠前アイコンをクリックし、 "SECRETS" を開きます

"+ New secret" をクリックします

スクリーンショット 2023-07-16 9.13.59.png

Name を "GITHUB_TOKEN" 、 Value を発行したトークンの値にし、 "in :house: My Hub" を選択して "+ Add" をクリックします

スクリーンショット 2023-07-16 9.16.09.png

"only this session" の場合、ノートブック上ではシークレットを読み込めますが、デプロイしたアプリからは読み込めなくなります

Slack のトークンについても Name を "SLACK_APP" にして同様に登録します

GitHub API の準備

gh =
  Req.new(
    base_url: "https://api.github.com",
    auth: {:bearer, System.fetch_env!("LB_GITHUB_TOKEN")},
    headers: [
      {"Accept", "application/vnd.github+json"},
      {"X-GitHub-Api-Version", "2022-11-28"}
    ]
  )

Kino.nothing()

Req を使って GitHub API にアクセスするため、クライアントを作成します

先程登録したシークレットは名前の先頭に "LB_" が付いて環境変数になっています

System.fetch_env!("LB_GITHUB_TOKEN") で、 GitHub トークンを取得し、 API の認証情報に設定しています

それ以外の設定は GitHub API の公式からコピーしています

最終行の Kino.nothing() は作成したクライアントの中身をユーザーに見せなくするために入れています

GitHub API の呼び出し

repo =
  "オーナー/リポジトリー"
  |> Kino.Input.text()
  |> Kino.render()
  |> Kino.Input.read()

if not String.contains?(repo, "/") do
  Kino.interrupt!(:normal, "オーナー/リポジトリー を入力してください")
end

report =
  case Req.get!(gh, url: "/repos/#{repo}/security-advisories") do
    %{status: 200, body: body} ->
      "リポジトリー #{repo} には #{length(body)} 個の報告があります"

    %{status: 404} ->
      Kino.interrupt!(:error, "リポジトリー #{repo} は存在しません")

    %{status: status} ->
      Kino.interrupt!(:error, "GitHub はステータス #{status} でエラーを返しました")
  end

GitHub API の "/repos/<オーナー>/<リポジトリー>/security-advisories" にアクセスし、セキュリティ報告を取得しています

今回は実際の報告結果ではなく、単に length(body) を表示しているので、結果は常に 1 になります

実行すると、以下のようなフォームが表示されます

スクリーンショット 2023-07-16 9.30.26.png

Kino.Input.text によってテキスト入力を作成し、正しく入力されていない場合("/"を含んでいない場合)は Kino.interrupt で先に進まないよう制御しています

テキスト入力に livebook-dev/livebook と入力し、 Continue をクリックします

スクリーンショット 2023-07-16 9.43.49.png

Slack へのメッセージ送信

req =
  Req.new(
    base_url: "https://slack.com/api",
    auth: {:bearer, System.fetch_env!("LB_SLACK_TOKEN")}
  )

channel =
  "Slack Channel"
  |> Kino.Input.text()
  |> Kino.render()
  |> Kino.Input.read()

if not String.starts_with?(channel, "#") do
  Kino.interrupt!(:normal, "送信先チャンネルを指定してください")
end

response =
  Req.post!(req,
    url: "/chat.postMessage",
    json: %{channel: channel, text: "新しい報告が来ました
#{report}"}
  )

case response.body do
  %{"ok" => true} ->
    "報告が送信されました!"

  %{"ok" => false, "error" => error} ->
    Kino.interrupt!(:error, "Slack 送信でエラーが発生しました #{error}")
end

GitHub と同じく環境変数 "LB_SLACK_TOKEN" から Slack のトークンを取得し、 Slack API を呼び出します

スクリーンショット 2023-07-16 9.49.39.png

Slack Channel に用意しておいたチャンネル名を入力し、 Continue をクリックします

スクリーンショット 2023-07-16 9.50.55.png

Slack にメッセージが来ました

スクリーンショット 2023-07-16 9.51.24.png

アプリのデプロイ

ここまでで処理の実装は完了です

あとはこれを Multi-Session Livebook App としてデプロイします

デプロイの設定、実行

Livebook の左メニューロケットアイコンから "APP" メニューを開き、 "Configure" をクリックします

スクリーンショット 2023-07-16 9.52.55.png

"Slug" (アプリをデプロイしたときの URL の末尾) に適当な値を入れます

"Session type" は "Multi-session" を選択します

"Deploy" をクリックします

スクリーンショット 2023-07-16 9.54.07.png

"APP" メニューにデプロイメントが追加されました

スクリーンショット 2023-07-16 9.56.07.png

セッションの開始

http://localhost:8080/apps/multi を新しいタブで開きましょう

セッションの確認モーダルが表示されるので、 "+ New session" をクリックします

スクリーンショット 2023-07-16 9.57.53.png

ノートブックからコードが除去され、入力フォームだけが残った画面が開きました

スクリーンショット 2023-07-16 10.00.22.png

"オーナー/リポジトリー" に "livebook-dev/livebook" を入力し、 "Continue" をクリックします

スクリーンショット 2023-07-16 10.02.02.png

"Slack Channel" にチャンネル名を入力し、 "Continue" をクリックします

スクリーンショット 2023-07-16 10.03.02.png

スクリーンショット 2023-07-16 10.03.24.png

ちゃんと Slack までメッセージが送信されました

新しいセッションの開始

http://localhost:8080/apps/multi をもう一つの新しいタブで開きましょう

すると、セッションの確認モーダルが表示され、既に動いているセッションが表示されます

スクリーンショット 2023-07-16 10.04.30.png

"+ New session" をクリックすれば、新しいセッションが開始され、再び初期状態からアプリを操作できます

スクリーンショット 2023-07-16 10.00.22.png

http://localhost:8080/apps/multi を更に新しいタブで開きましょう

スクリーンショット 2023-07-16 10.08.40.png

既に開いている二つのセッションが表示されています

下の方のセッションをクリックします

スクリーンショット 2023-07-16 10.03.02.png

この場合、既に実行済の状態でアプリが開きます

これは最初に開いていたタブと同じセッションなので、こちらのタブでリポジトリーを変更すると、その内容は最初のタブにも連動します

Livebook の "APP" メニューを見ると、二つのセッションが実行中になっていることが分かります

スクリーンショット 2023-07-16 10.11.51.png

Livebook トップの "Apps" メニュー http://localhost:8080/apps を開くと、二つのセッションにそれぞれ何人が接続しているかも分かります

スクリーンショット 2023-07-16 10.13.12.png

再デプロイ

Livebook の APP メニューから Configure を開き、 "List existing sessions" のチェックを外して "Deploy" をクリックします

スクリーンショット 2023-07-16 12.11.51.png

この状態でアプリを開くと、既存のセッションが表示されず、新しいセッションを開くことしかできなくなります

スクリーンショット 2023-07-16 9.57.53.png

デプロイする度にバージョン番号が増えていきますが、古いバージョンにアクセスしていたセッションはその時点のバージョンのままです

スクリーンショット 2023-07-16 12.14.23.png

## 既存セッションへの操作

"APP" メニューから各セッションを操作できます

スクリーンショット 2023-07-16 12.17.57.png

左下リンク :link: アイコンを開くと、当該セッションに参加できます

右下の左側ターミナルアイコンを開くと、デバッグモードでアプリが開きます

デバッグモードではアプリにコードが表示され、通常のノートブックとして編集、操作できます

スクリーンショット 2023-07-16 12.20.30.png

注意しないといけないのは、あくまでも当該セッションに対するデバッグなので、ここで変更した内容は元のノートブックに反映されません

変更結果を保存したい場合は普通のノートブックと同様、保存してください

セッションの右下停止アイコンをクリックすると、セッションを停止できます

スクリーンショット 2023-07-16 12.24.08.png

停止したセッションには参加できなくなり、代わりに右下ゴミ箱アイコンから削除できるようになります

まとめ

0.9 の Livebook Apps の時点でも凄かったですが、 Multi-Session Livebook Apps によって更に実用的になりました

いろんな処理を Elixir + Livebook で自動化できそうですね

13
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?