Python勉強1日目後半 BottleでTwitterAPI叩いてみる

More than 1 year has passed since last update.

ケーススタディ

Python3.4
Bottle
InteliJ
Twitterで何かする

前回までのあらすじ

python3.4、Intellij環境構築
bottleの基本的な使い方勉強
jinja2テンプレートの簡単な使い方
モジュール化

Twitterのtimelineにpostする

Requests-OAuthlibを使う

結果からいうと 失敗しました

Twitterライブラリもいっぱいあるけど、WebAPIはJSON送るだけなので
Authだけライブラリで行い、あとは HTTPリクエストを直で投げる事に
Twitterライブラリとは違いFacebookやGoogle+など他のAuthにも使えるし

ということで Requests-OAuthlib を使うことに

いつものように、
import requests_oauthlib
をし IntelliJでimportするが
not foundになり、解決できない!

色々と試したが結局 IntelliJで使う事をあきらめ
pipでインストールし、コマンドラインから起動させることに

まずはTwitterのAPI登録し、
consumer_key, consumer_secret, access_token, access_token_secret
を取得して 設定してください

import os
import bottle
import jinja2
import requests_oauthlib
from requests_oauthlib import OAuth1Session

from bottle import route, post, request, run
from bottle import TEMPLATE_PATH, jinja2_template as template

base_url = "https://api.twitter.com/1.1/"
update_url="statuses/update.json"


consumer_key="hoge"
consumer_secret="hoge"
access_token="hoge"
access_token_secret="hoge"


TEMPLATE_PATH.append("./template")



class Twitter:
    def __init__(self, consumer_key, consumer_secret, access_token, access_token_secret):
        self.twitter_ = OAuth1Session(consumer_key, consumer_secret, access_token, access_token_secret)

    def update(self, msg):
        param="{'status:': '" + msg + "'}"
        return(self.twitter_.post(base_url+update_url, param))


@route('/')
def HomeHandler_():
    return template("home.j2", posts="そのうちtimeline取得する")

@post('/1/twitter/post')
def UpdateHandler_():
    global twitter_
    msg = request.forms.get('status')
    print("post:"+msg)
    req = twitter_.update(msg)
    return template("home.j2", posts="そのうちtimeline取得する")


twitter_ = Twitter(secret.consumer_key, secret.consumer_secret, secret.access_token, secret.access_token_secret)


if __name__ == "__main__":
    run(host='localhost', port=1046, debug=True, reloader=True)


home.j2
{% extends "base.j2" %}

{% block content %}
  <div id="postform">
    <form method="POST" action="/1/twitter/post">
      <table>
        <tr><td><textarea cols="70" rows="3" name="status"></textarea></td></tr>
        <tr><td align="right"><input type="submit" name="doit" value="Update"></td></tr>
      </table>
    </form>
  </div>

<h2>Timeline</h2>
<i>aaa</i><br>
{% for post in posts %}
{{ post }}
{% endfor %}

{% endblock %}

コード的には ちゃんと出来ているような気もするのですが
動きません。。

2時間ほど頑張ってみましたが うまくtweetできなかったので
あきらめます

Tweepy

あっさりとライブラリ変えます。色々会ったのですが何となく
Tweepyというライブラリに決めました。理由はありません
ついでにモジュール化します

モジュール名は Twitter.py にします
mainのほうは
import Twitter
を追加し

Twitter.hogeの部分を モジュール名のネームスペースを加え
Twitter.Twitter.hoge にかえ

Twitter.py
# -*- encoding: utf-8 -*-
import tweepy



__author__ = 'miyatake_y'

base_url = "https://api.twitter.com/1.1/"
update_url="statuses/update.json"



class Twitter:
    def __init__(self, consumer_key, consumer_secret, access_token, access_token_secret):
        self.auth_ = tweepy.OAuthHandler(consumer_key,consumer_secret)
        self.auth_.set_access_token(access_token,access_token_secret)
        self.twitter_ = tweepy.API(self.auth_)

    def update(self, msg):
        print("Twitter.update:" + msg)
        return(self.twitter_.update_status(status=msg))

フォームからPOSTできるようになりました!
しかも IntelliJからも動かせるように!
でも、日本語が化けますね。
次はそこを対応しようとおもいます

日本語化対応

非常に簡単でした。
requestの時に decode() を呼ぶだけで大丈夫

msg = request.forms.decode().get('status')

これで日本語Postも可能に!

タイムライン取得&表示

タイムラインの取得じたいは簡単
Tweepyを使えばすぐ
twitter_.home_timeline()
で、statusオブジェクトのリストが帰ってくる。
引数は、ツイートを何個取ってくるかとか、何番目から取ってくるかなどで
デフォルトだと 最新から20個もってくる

print(twitter_.home_timeline()[0].text)
とすれば、 最新のTweetのテキストが表示される
statusオブジェクトにはテキスト以外に時間等の他のデータも入っている

今回は タイムラインのリストを取得し
jinja2のテンプレートエンジンにリストを渡し
テンプレート内で ループ処理することに

Twitterクラスにメソッド追加。
今思えば Tweepyを生で使う方が楽だと思った
```py3:Twitter.py
def home_timeline(self):
return(self.twitter_.home_timeline())


テンプレートに対し引数として statusリストを与える
```py3:main.py
    return template("home.j2", posts=twitter_.home_timeline())

そしてテンプレートは forで回す

home.j2
{% for post in posts %}
{{ post.text }} <br><hr>
{% endfor %}

これで、タイムラインを表示することができた!!

追加しようと思ってる機能

自分のPOSTを表示。テンプレート
API増やしたいから friendだかなんか。
ACCESS TOKENをプログラムで取得