Kaggle APIとSlack APIとGoogle Apps Scriptで新規カーネル投稿を監視する
はじめに
最近Kaggleにハマっています。今はQuoraのコンペをやっているところです。
NNなんも分からんけど楽しい!
Kaggle Advent Calendarのu++さんの記事を読んで自分も新規カーネルの投稿を監視する仕組みを作りたくなったのですが、u++さんの方法は自分のMacが通信できる状態にないといけないため、一番カーネルを読む時間が取りやすい電車内などで新規カーネルの投稿を監視できなくなってしまいます。
家のデスクトップでcronで叩いてもよかったのですがそのためだけにデスクトップを立ち上げておくのも少し気がひけるので今回は、スクリプトの定期実行が無料で簡単にできるGoogle Apps Sciptを用いてシステムを構築してみました。
コードは下記のリポジトリにて公開しています。
全体像
システムの全体像は
上の図のようになっています。全体の流れは以下の通りです。
- まずGoogle Apps ScriptからKaggle APIのエンドポイントを叩き、現在あるカーネルのリストを入手します。
- 次にこのリストをGoogle Spreadsheet内に作った簡易データベースと照合し、新しいカーネルがないかを調べます。
- 新しいカーネルが見つかった場合は時系列昇順に並べてシートの行末に追記していきます。また、新しいカーネルについてはSlack APIと連携して自分用slackにも通知を飛ばします。
Slack通知の様子
Kaggle APIでカーネルのリストを入手するとJSONの配列の形で送られてきます。1つ1つのカーネルに関してはかなり多くの情報が用意されているのですが(タイトル、作成者、GPU onかどうか、などなど)ほとんどがnullになっているので、実際に使えるのは、タイトル、作成者、オリジンからのパス、更新日時くらいかと思います。
これらを少し整形して送っている様子が上の通知の画像です。
使ってみて
やはり一覧表示されていると情報量に圧倒されてしまうので、変化があったときにだけ見るのは非常に役立っています。これからもどんどん利用していきたいと思います。
技術的な話
Kaggle APIについて
今回は公式が出しているKaggle APIクライアントを使えないので、APIクライアントのソースを読んでエンドポイントの叩き方を調べる必要がありました。
このAPIクライアントはSwaggerのコードジェネレート機能を用いて構築されているらしく読んでいてなかなか勉強にもなりました。
まず、APIのエンドポイントについてですが、KaggleSwagger.ymlの中に記述されています。
また認証に関しては、複数のファイルに分散していますが、kaggle.jsonの情報を用いてBasic認証を行なっているようです。この際のエンコーディングなどはconfiguration.pyで行なっています。
挙動を定義するために--competitionなどで与えるパラメータはURLの中にクエリパラメータとして入れることができるようになっています。
Spreadsheetによる簡易DBについて
Google Apps Scriptの強みはやはりGoogleのサービスを操作できることかと思います。
今回はKaggle APIで作成日順にソートとして得られたカーネルの情報を、初回実行時にスプレッドシートに順に入れておき、次回以降Kaggle APIを叩いて得られたときはJSON配列とスプレッドシートの中身の配列の長さを用いて新規カーネルがあるかどうかを判定しています。
また、このように順番をソートしておくことで新しいカーネルがあった場合もソートされている上位n個のカーネルが新規である、と判定することができ、過去に投稿があったものかどうかの判定が簡素になっています。
Slack連携
Slackへの通知はGASライブラリSlackAppを用いています。
このライブラリを使うことで、SlackのAPIトークンを渡すだけでSlack通知ができるようになります。
テスト
今回は小規模なのであまり必要はないのですが今後拡張することも考えてGSUnitを用いてテストを行っています。
クレデンシャルの扱いについて
Google Apps Scriptでは、クレデンシャルなどのハードコーディングを防ぐ仕組みとしてPropertiesServiceというものがあります。これを用いることでキー:バリューの形で保存したプロパティを呼び出すことができます。
今回はこれを用いてSlackのAPIトークン、Kaggle APIのBasic認証のトークン、そしてspreadsheetのIDを保存しています。
なお、この情報はWebUIなどでみたときには普通に見えてしまうため、共用のアカウントなどで行うことはオススメしません。