GoogleAppEngineでtwitterAPIをOAuth認証で使う(1)
twitter APIでBASIC認証を使うのが6月30日までに決まったそうで。お仕事でtwitterのAPIを使ったことがありますが、BASIC認証のままでして。これからはOAuth認証だよ、ということなので試してみよう、と思いました。そうおもっただけならいいんですが、なぜかGoogleAppEngineで試してみる結果に...。
アカウントを用意する
テスト用のアカウントを用意しました。外部アプリケーションの設定(http://twitter.com/apps)をします。すると、
- Consumer key
- Consumer secret
というのが設定されます。ええと、ここら辺は「ASCII.jp:ゼロから分かる、GAE&Twitter API開発の始め方|Twitter&Google App Engineで始めるWebプログラミング入門」で。
このあたりで、いろいろと種類があるのがわかりにくい。
ライブラリ
「ASCII.jp:サンプルコードで分かるGAE&Twitter API開発|Twitter&Google App Engineで始めるWebプログラミング入門」見てインストール。
simple_cookieと、oauthのライブラリを入れました。ちょっと意外だったんですけれど、simplejsonって、djangoに入っていたのか...
pythonって、ライブラリーはどこらへんにまとまっているのかが、よくわからず...。Perlのcpan、PHPのpearと並ぶような整理されたのがわかるといいなあ(あるのかもしれないけれど)
main.py
- これでlocalhostでも動きます
- webappというフレームワークを使っています。GoogleAppEngineに標準で使えるフレームワークの一つ
- 簡単なフレームワークということらしいのです
- main()にてURLのマッピングをしているのですが、一つ一つマッピングするのは面倒な気がする
- URLマッピングで、(.*)でマッチしたところが、modeになります
- 処理の流れは、http://localhost:8080/loginで、ログインと認証処理。その後、http://localhost:8080/に戻ります。すると、自分のタイムラインが表示されます
- 表示にはwebappのテンプレートエンジンを使っています
#!/usr/bin/env python # -*- coding: utf-8 -*- import os import wsgiref.handlers from google.appengine.ext import webapp from google.appengine.ext.webapp import util from google.appengine.ext.webapp import template import oauth from simple_cookie import Cookies from django.utils import simplejson CONSUMER_KEY = '' CONSUMER_SECRET = '' COOKIE_EXPIRE_TIME = '300' TIMELINE_COUNT = '30' class MainHandler(webapp.RequestHandler): def get(self, mode=""): callback_url = "%s/verify" % self.request.host_url client = oauth.TwitterClient(CONSUMER_KEY, CONSUMER_SECRET,callback_url) cookie = Cookies(self, max_age=COOKIE_EXPIRE_TIME) if mode == '': param = {'count': TIMELINE_COUNT} timeline_url = "http://api.twitter.com/1/statuses/home_timeline.json" response = client.make_request(url=timeline_url,token=cookie["user_token"],secret=cookie["user_secret"],additional_params=param) results = simplejson.loads(response.content) View.layout['content'] = View.view_dir + 'index.html' params = {'layout':View.layout, 'datas':results} filepath = os.path.join(os.path.dirname(__file__), 'layouts', View.layout_file) html = template.render(filepath, params) self.response.out.write(html) if mode == 'login': self.redirect(client.get_authorization_url()) if mode == 'logout': cookie.delete_cookie("user_token") cookie.delete_cookie("user_secret") cookie.delete_cookie("screen_name") if mode == "verify": #VerityAuth(self, client, cookie) auth_token = self.request.get("oauth_token") auth_verifier = self.request.get("oauth_verifier") user_info = client.get_user_info(auth_token, auth_verifier=auth_verifier) cookie["user_token"] = user_info["token"] cookie["user_secret"] = user_info["secret"] cookie["screen_name"] = user_info["username"] self.redirect('/') class View: layout_file = 'layout.html' view_dir = '../views/' layout = { 'title':'New', 'header':'header.html', 'footer':'footer.html', } def main(): application = webapp.WSGIApplication( [ ('/(.*)', MainHandler) ], debug=True) wsgiref.handlers.CGIHandler().run(application) if __name__ == '__main__': main() else: print 'error'
テンプレート
- views/index.html
<table class="data"> {% for data in datas %} <tr> <td>{{ data.id }}</td> <td>{{ data.user.screen_name }}<img src="{{ data.user.profile_image_url }}" /><br />{{ data.text }}</td> <td>{{ data.created_at }}</td> <td>{{ data.source }}</td> </tr> {% endfor %} </table>
- layouts/index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /> <title>{{ layout.title }}</title> </head> <body> {% include layout.header %} {% include layout.content %} {% include layout.footer %} </body> </html>
- laytous/footer.html
<div>footer</div>
- layouts/header.html
<div>header</div>