Twitter APIを使って自分のツイートのアナリティクスを取得したくなり、Twitter API v2を始めることにしました。
Twitter API v2はOAuth2.0を使う必要があるようですが、OAuth2.0でTokenを取得するにはローカルでサーバーを立ち上げる必要がありそう。いちいちフレームワークレベルのWebサーバーを立ち上げるのはめんどくさい。
そこでPythonのHTTPServer/SimpleHTTPRequestHandlerを使って一時的にWebサーバーを立ち上げてcodeだけ取得した後にAccess TokenとRefresh Tokenを取得することにしました。
これって、結構需要が多いんじゃないかな?と勝手に想像して、記事にすることにしました(栄えある1回目の投稿)
クライアントID/クライアントシークレット取得
Twitterのdeveloperサイトから取得してください。この辺りは、ほかの方の記事でも紹介されているので割愛します。
settings.jsonの作成
上記で取得したクライアントIDとクライアントシークレットをコードの中に入れるのではなく、外部から読み込むことにします。今後、Twitterのアナリティクスを取得するときにも、この設定が役つと思い、この形式にしました。
下記settings.jsonファイルを、Tokenを取得するファイルや今後Twitter APIを実行するフォルダと同階層においてください。
settings.json
{
"client_id" : "<取得したクライアントID>",
"client_secret" : "<取得したクライアントシークレット>",
"redirect_uri" : "http://localhost:8080/"
}
注意! Access TokenとRefresh Tokenをテキストで保存します
これから紹介するコードを実行すると「token」フォルダに「access_token.txt」と「refresh_token.txt」が作成され、テキストの中に平文で各トークンが保存されます。Refresh Tokenは比較的長く利用可能で、Refresh TokenからAccess Tokenを取得できるようになります。Access Token(Refresh Tokenも)が漏れると、Twitter API実行が可能になるため注意が必要です。作成されたテキストファイルを外部に共有しないように気を付けてください。
Token取得と保存
注意にも記載した通り、下記コードを実行すると「Token」フォルダにAccess TokenとRefresh Tokenが保存されます。
下記コードを実行すると、ブラウザが起動し、クライアントID等を取得したTwitterアカウントでアプリの承認を求められます。承認を許可すると、一時的に立ち上げたローカルのWebサーバーにとび、Tokenが取得できます。
コードは下記の通り
twitter_API_get_token.py
import base64
import hashlib
import os
import re
import json
import requests
from requests_oauthlib import OAuth2Session
from http.server import HTTPServer, SimpleHTTPRequestHandler
import http.server
import socketserver
from urllib.parse import urlparse, parse_qs
import webbrowser
HOST = "localhost"
PORT = 8080
global auth_code
auth_code = None
ini_json_file = open('./settings.json', 'r')
ini_json_data = json.load(ini_json_file)
os.makedirs("./token/", exist_ok=True)
def store_tokens(access_token, refresh_token):
store_token_place = "./token/"
access_token_file = store_token_place + "access_token.txt"
refresh_token_file = store_token_place + "refresh_token.txt"
with open(access_token_file,'w', encoding='utf-8-sig',newline="") as f:
f.write(access_token)
with open(refresh_token_file,'w', encoding='utf-8-sig',newline="") as f:
f.write(refresh_token)
client_id = ini_json_data["client_id"]
client_secret = ini_json_data["client_secret"]
redirect_uri = ini_json_data["redirect_uri"]
scopes = ["tweet.read", "tweet.write", "users.read",\
"offline.access", "list.read", "like.read", "like.write"]
code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8")
code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier)
code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest()
code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8")
code_challenge = code_challenge.replace("=", "")
oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes)
auth_url = "https://twitter.com/i/oauth2/authorize"
authorization_url, state = oauth.authorization_url(
auth_url, code_challenge=code_challenge, code_challenge_method="S256"
)
webbrowser.open(authorization_url)
class ServerHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
global auth_code
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
self.wfile.write(b"<h1>Authneticated</h1>")
parsed_path = urlparse(self.path)
query = parse_qs(parsed_path.query)
auth_code = query['code'][0]
#print(auth_code)
with socketserver.TCPServer((HOST, PORT),ServerHandler) as server:
print('http server start')
server.handle_request()
print('http server shutdown')
token_url = "https://api.twitter.com/2/oauth2/token"
token = oauth.fetch_token(
token_url=token_url,
client_secret=client_secret,
code_verifier=code_verifier,
code=auth_code,
)
access = token["access_token"]
refresh = token["refresh_token"]
#print("access token is ",access)
#print("refresh token is ",refresh)
data = {
'refresh_token': refresh,
'grant_type': 'refresh_token',
}
response = requests.post(token_url, data=data, auth=(client_id, client_secret))
jsondata = response.json()
#print(jsondata["access_token"], jsondata["refresh_token"])
store_tokens(jsondata["access_token"], jsondata["refresh_token"])
いかがでしたでしょうか? 参考になれば幸いです。
最後にpythonの書籍のご紹介です。
「Pythonとは?」や「AIプログラミングとは?」ということが、深く理解できるわけではないのですが、書籍に書いてある通りに入力してみると、手っ取り早く「PythonのAIプログラミングってこんなことができるようになるんだ!」ということが分かるようになる書籍です。
私も購入して、実際にやってみて面白かったので、初心者あたりの方にはお勧めです。
今後、今回取得したTokenを使ってアナリティクスを取得するコードも紹介していく予定です。
コメント