Hello Wor.log

IT系大学生4人による備忘録のようなもの

Bottle+Tweepyで作ったアプリをHerokuでデプロイしてみる

こんにちは、CPPXのC1です。とても久しい更新になりました。
今回は、PythonのWebフレームワークであるBottleと、同じくPythonのTwitterAPIを楽に叩けるライブラリであるTweepyを使って作った簡単なアプリを、PaaSの一つであるHerokuを用いてデプロイしてみたいと思います。
Python及び各種ライブラリ、Herokuのインストール等は、頑張ってください!!

Bottleの基本形

まずはBottleの基本形から
localhostの/(ルート)に"Hello World!"したい場合は、以下のようなプログラムになります。

# -*- coding:utf-8 -*-

from bottle import route, run


@route('/') #ここでURLの指定をしている
def hello():
    return "Hello World!" # ここで表示内容を記述


run(host='localhost', port=8080, debug=True)

すごく簡単に書けて、いい感じですね。

のちのち必要になってくるので、HTMLの内容を表示する方法も紹介しておきます。
index.htmlを表示させたい場合は、以下のようなプログラムになります。htmlファイルは、viewsディレクトリ以下に配置するのを忘れないでくださいね。

# -*- coding:utf-8 -*-

from bottle import route, run, template


@route('/') 
def hello():
    return template("index") #ここでindex.htmlを読み込んでいる

run(host='localhost', port=8080, debug=True)

こちらも簡単に書けて、いい感じですね。

Tweepyの基本形

次はTweepyの基本形を
鍵は、Twitter Appsから取得したとして、任意のアカウントにつぶやきを投稿するには、以下のようなプログラムを作成します。

#coding: UTF-8

import tweepy

C_KEY = "Consumer Key (API Key)の欄の文字列"
C_SECRET = "Consumer Secret (API Secret)の欄の文字列"
A_KEY = "Access Tokenの欄の文字列"
A_SECRET = "Access Token Secretの欄の文字列"

auth = tweepy.OAuthHandler(C_KEY, C_SECRET)
auth.set_access_token(A_KEY, A_SECRET)
api = tweepy.API(auth)
api.update_status("Hello World!")# "Hello World!"を投稿する

実行すれば、1回"Hello World!"が投稿されます。簡単で良いですね。

Bottle + Tweepy

さて、上記の2つを組み合わせて、Web上で入力した任意の文字列を、特定のアカウントにつぶやくというアプリを作ってみます。
何から作るか難しいところですが、まずはhtmlから。1つテキストエリアと、送信用のボタンがあれば十分そうです。

<!DOCTYPE html>
<html lang=ja>
  <head>
    <meta charset="UTF-8">
    <title>Test</title>
  </head>

  <body>
    <form onsubmit="return false;" method="POST" action="/">
      <textarea name="msg"></textarea>
      <input type="button" value="ツイートする" onclick="submit();">
    </form>
  </body>
</html>

次に、Pythonのプログラムです。若干色々付いてますが、基本はただ2つを組み合わせただけです。

# -*- coding: utf-8 -*-
from bottle import route, run, template, request, post, get
import tweepy
import sys, codecs
sys.stdout = codecs.getwriter("utf-8")(sys.stdout) #文字化け対策


@route("/")
def index():
    return template("index")


@post("/")
def msg():
    msg = request.forms.msg #htmlから文字列を受け取る

    C_KEY = "Consumer Key (API Key)の欄の文字列"
    C_SECRET = "Consumer Secret (API Secret)の欄の文字列"
    A_KEY = "Access Tokenの欄の文字列"
    A_SECRET = "Access Token Secretの欄の文字列"

    auth = tweepy.OAuthHandler(C_KEY, C_SECRET)
    auth.set_access_token(A_KEY, A_SECRET)
    api = tweepy.API(auth)
    api.update_status(msg) #受け取った文字列をツイート

    return template("index") + "ツイートしたよ!"


run(host="localhost", port="8080", debug=True,reloader=True)

こんな感じで良さそうです。改善の余地はありそうですが。
ともあれ、これでWebアプリから、特定のアカウントにつぶやきを投稿することが出来るようになりました!

Herokuでデプロイする

最後に、ローカルで動いているだけだとなんだかつまらないので、Herokuを使ってデプロイしてみましょう。
やることとしては、

  • Pythonプログラムの最後の行等を少し修正
  • アプリケーションタイプとエントリポイントを記述するProcfileの作成
  • 依存ライブラリ一覧を記述したrequirements.txtの作成
  • Pythonのバージョンを明示的に指定するruntime.txtの作成

の4点ですかね。基本の形はそのままでデプロイ出来ます。

Pythonプログラム修正

今のままだとrun()でlocalhostを指定しているので、デプロイ用に書き換えましょう。

import os #import文の一番上にosをインポート
from bottle import route, run, template, request, post, get
...

#run(host="localhost", port="8000", debug=True, reloader=True) 
run(host="0.0.0.0",port=int(os.environ.get("PORT",5000))) #最終行、localの方をコメントアウトし、このように記述

こんな感じで大丈夫です。

Procfileの作成

$ echo web: python main.py > Procfile 

結論から書くと、これで大丈夫です。main.pyの部分は自分のPythonプログラムと同じ名前にしてください。

requirements.txtの作成

依存ライブラリを記述したファイルが必要になります。pyenvなどでプロジェクトごとにライブラリを管理している方は、

$ pip freeze > requirements.txt

で大丈夫です。
そうじゃない方(がいるのか分かりませんが)のために

bottle==0.12.11
oauthlib==2.0.1
requests==2.12.4
requests-oauthlib==0.7.0
six==1.10.0
tweepy==3.5.0

こんな感じになれば問題ないです。ちょっとバージョンが古いかもしれません。

runtime.txtの作成

最後です。うっかりPython2系で動いてしまうと"ツイートしたよ!"辺りで怒られてしまったり、良くないので、安全のためにruntime.txtを作成しておきましょう。

python-3.5.2

なんてことないですね。Python3系なら何でも良いかと思います。

最後に

お疲れ様でした。これで複数の端末や身内での共同アカウントなどでいちいちログインせずにつぶやけるので、ちょっと楽になる、かもしれません。 Pythonのバージョンを見ると分かる通り、少し前に作ったものなのでWarning吐いてるっぽくてリファクタリングしなきゃかなあという感じですね。 がんばってブログ更新するぞー