utamaro’s blog

誰かの役に立つ情報を発信するブログ

stackoverflowのapiをpythonで使ってみた

stackoverflowのoauthを試してみたので、そのときにやったことを紹介します。

基本的なステップについてはすべてドキュメントにかかれていたので、試す際に書いたコードを載せます。

ドキュメントはこちらです。

https://api.stackexchange.com/docs/authentication#scope

import requests
import json

client_id = '12345'
client_secret = 'xxxxxxxxxxxxxxx'

scope = 'read_inbox'
redirect_uri = 'http://localhost'

def step1():
    step1 = requests.get(
        'https://stackoverflow.com/oauth',
        {
            'client_id': client_id,
            'scope': scope,
            'redirect_uri': redirect_uri,
        }
    )
    print(step1)
    print(step1.url)

def step2(code):
    step2 = requests.post(
        'https://stackoverflow.com/oauth/access_token/json',
        {
            'client_id': client_id,
            'client_secret': client_secret,
            'code': code,
            'redirect_uri': redirect_uri,
        }
    )
    print(step2)
    obj = json.loads(step2.text)
    access_token = obj.get('access_token')
    expires = obj.get('expires')
    print(access_token, expires)
    '{"access_token":"xxxxxxxxxxxxxxx","expires":86400}'

if __name__ == '__main__':
    step1()
    # step2()

step1について

step1ではcodeというものを取得します。

requests.getで取得した文字列の中に、↓のようなurlが含まれているので、そのurlをブラウザで開きます。

https://stackoverflow.com/users/login?xxxxxxxxxxxxxxxxxx

Django等で作成している場合は、urlにリダイレクトする感じで良いはずです。

ブラウザで開くと、stackoverflowのログイン画面が開きます。

ユーザーがアプリケーションのアクセスを許可すると、リダイレクトurlへリクエストが来ます。

サンプルのコードは、サーバーサイドの実装はしていないので、ブラウザのurlを見ます。

ここで取得したcodeをコピーして、step2を実行します。

step2

step2は簡単です。

step1で取得したcodeをpostで送ると、access_tokenとexpireを取得できます。

このaccess_tokenを使って、ユーザーが持っている情報を取得できます。

DjangoではSocialAuth用のテーブルにaccess_tokenを保存していたので、DBに保存しても良いでしょう。

そして、有効期限が切れたらもう一度tokenを発行してもらう形で対応できると思います。

おまけ

認証が必要ないapiもあります。

stackoverflowでログインが不要な処理はできます。

ドキュメントはこちらです。

https://api.stackexchange.com/docs

例えば、回答一覧を取得するなら↓で実行できます。

def get_answers():
    url = 'https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow'
    r = requests.get(url)
    print(r.text)