Flask と Tweepy を使った Twitter 連携アプリ

次のプログラムを参考にしました。
[【Python】Flask+TweepyでTwitter連携アプリを作る](https://shirokai.hatenablog.com/entry/flask-tweepy)

開発段階では、Callback URL を http://0.0.0.0:5000 に設定して下さい。
![twitter_dec03.png](https://qiita-image-store.s3.amazonaws.com/0/179446/ce36502f-263d-0cef-2130-17cf2361e0c0.png)

プログラムが完成した時の動作です。
python flask-tweepy.py でサーバーを起動して、
ブラウザーで、http://0.0.0.0:5000/　にアクセスします。
![flask_dec0301.png](https://qiita-image-store.s3.amazonaws.com/0/179446/ce64c61a-9571-9350-ba61-636d477eded1.png)


連携アプリ認証をクリックします。
![flask_dec0302.png](https://qiita-image-store.s3.amazonaws.com/0/179446/b7c07d8d-a930-75c7-d844-df302d3e1f31.png)

Authorize app をクリックします。
![flask_dec0303.png](https://qiita-image-store.s3.amazonaws.com/0/179446/e29ee64a-1d52-4283-d3a9-d61244015f6a.png)

フォルダーの構造

```text
├── .env
├── flask-tweepy.py
└── templates
    └── index.html
```

```py:flask-tweepy.py
# -*- coding: utf-8 -*-
#
#	flask-tweepy.py
#
#					Dec/03/2018
#
# ------------------------------------------------------------------
"""
Flask+TweepyによるTwitter連携アプリのサンプル．
連携アプリ認証を行いタイムラインを表示する．
"""
import os
import json
import sys
import tweepy
from flask import Flask, session, redirect, render_template, request
from os.path import join, dirname
from dotenv import load_dotenv
#
dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)
# --------------------------------------------------------------------------
app = Flask(__name__)
app.secret_key = os.environ['SECRET_KEY']
# --------------------------------------------------------------------------

CONSUMER_KEY = os.environ['CONSUMER_KEY']
CONSUMER_SECRET = os.environ['CONSUMER_SECRET']

# --------------------------------------------------------------------------
@app.route('/')
def index():
	sys.stderr.write("*** root *** start ***\n")
	""" root ページの表示 """
	# 連携アプリ認証済みなら user の timeline を取得
	timeline = user_timeline()

	# templates/index.html を使ってレンダリング．
	sys.stderr.write("*** root *** end ***\n")
	return render_template('index.html', timeline=timeline)


# --------------------------------------------------------------------------
@app.route('/twitter_auth', methods=['GET'])
def twitter_auth():
	sys.stderr.write("*** twitter_auth *** start ***\n")
	sys.stderr.write(CONSUMER_KEY + "\n")
	sys.stderr.write(CONSUMER_SECRET + "\n")
	redirect_url = ""
	""" 連携アプリ認証用URLにリダイレクト """
	# tweepy でアプリのOAuth認証を行う
	sys.stderr.write("*** twitter_auth *** ccc ***\n")
#
	auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
	sys.stderr.write("*** twitter_auth *** ddd ***\n")

	try:
		sys.stderr.write("*** twitter_auth *** eee ***\n")
		# 連携アプリ認証用の URL を取得
		redirect_url = auth.get_authorization_url()
		sys.stderr.write("*** twitter_auth *** fff ***\n")
		sys.stderr.write("redirect_url = " + redirect_url + "\n")
		# 認証後に必要な request_token を session に保存
		session['request_token'] = auth.request_token
		sys.stderr.write("*** twitter_auth *** ggg ***\n")
		sys.stderr.write("auth.request_token = " + json.dumps(auth.request_token) + "\n")
		sys.stderr.write("*** twitter_auth *** hhh ***\n")
		sys.stderr.write("auth.request_token['oauth_token'] = " + auth.request_token['oauth_token'] + "\n")
		sys.stderr.write("auth.request_token['oauth_token_secret'] = " + auth.request_token['oauth_token_secret'] + "\n")
	except Exception as ee:
#	except tweepy.TweepError, e:
		sys.stderr.write("*** error *** twitter_auth ***\n")
		sys.stderr.write(str(ee) + "\n")

	# リダイレクト
	sys.stderr.write("*** twitter_auth *** end ***\n")
	return redirect(redirect_url)
#
# --------------------------------------------------------------------------
def user_timeline():
	sys.stderr.write("*** user_timeline *** start ***\n")
	if 'request_token' in session:
		sys.stderr.write("session['request_token'] = " + json.dumps(session['request_token']) + "\n")
	sys.stderr.write("*** user_timeline *** bbb ***\n")
	""" user の timeline のリストを取得 """
	# request_token と oauth_verifier のチェック
	token = session.pop('request_token', None)
	verifier = request.args.get('oauth_verifier')
	if token is None or verifier is None:
		return False  # 未認証ならFalseを返す

	# tweepy でアプリのOAuth認証を行う
#
	auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)

	# Access token, Access token secret を取得．
	auth.request_token = token
	try:
		auth.get_access_token(verifier)
	except Exception as ee:
		logging.error(str(ee))
		return {}

	# tweepy で Twitter API にアクセス
	api = tweepy.API(auth)

	# user の timeline 内のツイートのリストを最大20件取得して返す
	return api.user_timeline(count=20)
#
# --------------------------------------------------------------------------
if __name__ == "__main__":
	sys.stderr.write('*** app start! ***\n')
	port = int(os.environ.get("PORT", 5000))
	app.run(host='0.0.0.0', port=port)
# --------------------------------------------------------------------------
```

```html:templates/index.html
<!DOCTYPE html>
<html>
<head>
  <title>Flask + Tweepy Sample Application</title>
</head>
<body>
  <h1>Flask + Tweepy Sample Application</h1>
  {% if timeline == False %}
    <p><a href="{{ url_for('twitter_auth') }}">連携アプリ認証</a></p>
  {% else %}
    <!-- 取得した timeline のテキストを表示 -->
    {% for status in timeline %}
      <p>{{ status.text }}</p>
      <hr>
    {% endfor %}
  {% endif %}
  <footer>
	Dec/03/2018 AM 09:26<p />
  </footer>
</body>
</html>
```

```text:.env
SECRET_KEY=h12345
CONSUMER_KEY=vw12345
CONSUMER_SECRET=gWb12345
```