python-twitter-v2を使用するときは、timeoutを設定した方が良いという話
python-twitter-v2とは
Twitter API V2を叩くためのラッパーです。
pythonでpip install python-twitter-v2
でインストールできます。
from pytwitter import Api
api = Api(
consumer_key = 'consumer_key',
consumer_secret = 'consumer_secret',
access_token = 'access_token',
access_secret = 'access_secret'
)
try:
api.create_tweet(text = 'Hello World')
except:
print('Twitter投稿エラー')
と、シンプルなコードでTwitter API V2経由のツイートが実現出来て便利です。
何が起きたか?
定時実行しているプログラムが、何もエラーを吐かずに動作を停止していました。
前項の例のようにtry-except
でcreate_tweet
失敗時にcatchするようにしているのですが、ログを調査するとどうもcreate_tweet
実行後の処理を通っていない模様。
実行時刻は2023/03/18 15:29頃。
SNSで検索してみると、どうも当該時刻前後でTwitterがダウンしていたらしいです。
プログラムの挙動とTwitterの障害情報を見る限り、requestしてもresponseが返らず、ずっと待機していたように見えます。
python-twitterの処理を追う
resp = self.session.request(
url=url,
method=verb,
params=params,
data=data,
auth=auth,
json=json,
timeout=self.timeout,
proxies=self.proxies,
)
RequestsのSessionからrequest
をしていて、timeout
はself.timeout
の値が使用されています。
def __init__(
self,
bearer_token: Optional[str] = None,
consumer_key: Optional[str] = None,
consumer_secret: Optional[str] = None,
access_token: Optional[str] = None,
access_secret: Optional[str] = None,
client_id: Optional[str] = None,
client_secret: Optional[str] = None,
application_only_auth: bool = False,
oauth_flow: bool = False, # provide access with authorize
sleep_on_rate_limit: bool = False,
timeout: Optional[int] = None,
proxies: Optional[dict] = None,
callback_uri: Optional[str] = None,
scopes: Optional[List[str]] = None,
) -> None:
self.session = requests.Session()
self._auth = None
self._oauth_session = None
self.consumer_key = consumer_key
self.consumer_secret = consumer_secret
self.client_id = client_id
self.client_secret = client_secret
self.timeout = timeout
コンストラクタでself.timeout
が設定されているのですが、初期値がNone
になっていました。
Requestsのtimeout
Requestsのドキュメントによると、timeoutは設定すべきとされています。
timeoutにはconnect
(サーバとの接続の確立)とread
(サーバからresponseが返ってくる)の二種類があり、
- 両方に同じ値を設定する方法
r = requests.get('https://github.com', timeout=5)
- それぞれにタプルで値を設定する方法
r = requests.get('https://github.com', timeout=(3.05, 27))
の二通りの書き方があります。
python-twitter-v2のtimeout
python-twitter-v2
のコンストラクタで設定されるself.timeout
の値がそのままRequestsで使用されているので、floatかタプルで設定できそうに見えますが、コンストラクタを見ると
timeout: Optional[int] = None,
と、intが要求されているので、念のためintで値を設定してあげるとよいかと思われます。
api = Api(
consumer_key = 'consumer_key',
consumer_secret = 'consumer_secret',
access_token = 'access_token',
access_secret = 'access_secret',
timeout = 30
)
これで、create_tweet
などでTwitterへrequestを送る際、タイムアウトしたらexceptで拾えるようになります。
まとめ
Twitterが落ちたらプログラムが止まるので、python-twitter-v2
を使用する際はtimeoutを設定しておきましょう。
Discussion