herokuでPython製LINEbot+WebAppをCIする

LINE Messaging API + line-bot-sdk によるPythonでのチャットボット作成と,同等機能をもつWebアプリケーションを同時に作成し,herokuへデプロイ,継続的インテグレーションでmasterへのpushで自動デプロイさせました。

コードの詳細等はそもそもゴー☆ジャスをつくるをLINE BotとWebアプリ化したリポジトリがあるので,そちらを参照すること。

atsukoba/GorgeousApp

キミのハートに、レボ☆リューション!. Contribute to atsukoba/GorgeousApp development by creating an account on GitHub.

Webアプリ

herokuの下準備

まず,テキスト処理系のモノをherokuにデプロイするならばMeCab+mecab-python等の形態素解析器を入れたい。ので,buildpackを複数入れられるheroku-buildpack-multiを選択し,pythonとlinuxbrewのbuildpackを入れることでMeCab等のbrew installを可能にする

まずheroku cli。

1
2
brew tap heroku/brew && brew install heroku
heroku create --buildpack https://github.com/heroku/heroku-buildpack-multi

.buildpackへは以下を

1
2
https://github.com/heroku/heroku-buildpack-python.git
https://github.com/sunny4381/heroku-buildpack-linuxbrew.git

linuxbrew用の.celler

1
2
mecab
mecab-ipadic

と書いておき,requirements.txtも適切にかけば環境が整う。

以下を参照すると良い。(sklearnを動かすためにbuildpack-multiでcondaを入れている)

herokuでpython+django+scikit-learn+mecab(1)

LINE Developers / Messaging API の設定

screenshot

各種アクセストークン等取得しておく。
以下が多分文字通りわかりやすい。

LINE BOTの作り方を世界一わかりやすく解説(1)【アカウント準備編】

flaskでAPIを書く

LINE bot用のテンプレート (app.py) があり,それを使う。そこでは/callbackへのPOSTに対して返答を行うので,それに加えて,最低限ルートへのGET, POSTの処理を書いておく。(flask.render_template()でテンプレートHTMLを返すようにしておく)

ここで,テキスト処理用のモジュールを読んでおいて,POSTで入力されたテキストに対しての返答をJSONで受け取り,jinja2で扱えるようにrender_templateに渡してあげる。

linebot.LineBotAPIlinebot.WebhookHandlerのインスタンス化に必要なCHANNEL_ACCESS_TOKENCHANNEL_SECRETは環境変数に入れておき,os.environ.getで取得する。heroku上では管理画面から登録し,ローカルでのテストではテキトーに何か入れておく。

app.run(debug=True)でAPIのテストをする。

Jinja2を書く

テキスト処理なので,最低限入力ボックスと出力結果のUIはほしい。ので,HTMLとCSSを書く。flaskのappと同階層にtemplate/を作成し,そこにhtmlを書いていく。

普通に

1
2
3
<form action="/" method="POST">
<input type="text" name="input"/>
</form>

のように記入すればPOSTできるし,Jinja内では,2重ブラケット内で

1
2
3
<div id="data">
{{ data["key] }}
</div>

render_template()内に渡されたキーワード変数がそのまま辞書としてアクセスできる。

ただ,二重ブラケット内で素のPythonが書けるわけではない(とくにループやデータのキャストとか)ので,以下等を参照すると良い。

pythonのためのテンプレートエンジン「Jinja2」便利な機能

templates/と同階層にstatic/を作成しておけば,そこにcssやjsを書いてフロントをすこしいじれる。私はここでsass/内にsassを書き,css/style.cssへコンパイルすることで,

1
<link rel="stylesheet" href="/static/css/style.css">

のようにいつもどおりheadから読んで使っている。

herokuとGitHubの連携

herokuで動かすために,Procfileを書く。
wsgiとしてgunicornを用いるのが楽で,ポピュラーというかflaskだと必須か。
process typeはwebに設定し,gunicornを起動する。

web: gunicorn app.app:app --log-file=-

アプリケーションのインスタンスflask.Flaskを指定してあげる。
アプリケーションモジュール:アプリケーションインスタンス/関数という指定方法。

Gunicorn - Python WSGI HTTP Server for UNIX

ss

その後はGitHub上にリモートレポジトリを作成し,herokuのダッシュボード上で認証・連携をする。この時にGUIでconfig varsからLINEから発行されたアクセストークン等を登録できる。

あとは,普通にgit pushすれば,デプロイが走る。
デプロイ中のログに加えPythonからloggingprintで出力した内容もダッシュボードのログから確認できるため,そこで逐一チェックすればまあ動くものは作れるはず。