

python3でTwitterAPIにリクエストを送り、返ってきた値を格納するというコードを書きました。  
①ライブラリでOAuth認証をする  
②twitterAPIにリクエストを送る  
③APIのリクエスト上限をrequests_limitに格納する  
という内容になっています。  
この①のOAuth認証の例外処理の部分をメソッドにしたいのですがうまくかけません。例外処理でTwitterへのリクエストがうまくいかなかった時、OAuｔｈ認証をやり直し再度実行するメソッドを書きたいのです。

[code]

    from requests_oauthlib import OAuth1Session
    CK = "xxxxx" #Consumer key
    CS = "xxxxx" #Consumer secret
    AT = "xxxxx" #Access token
    AS = "xxxxx" #Access token secret
    twitter = OAuth1Session(CK, CS, AT, AS)#認証処理
    request_status_url = "https://api.twitter.com/1.1/statuses/retweets/:id.json"#リクエストURL
    for i in range(3):#適当に３回
        #↓↓↓↓↓メソッドにしたいところ↓↓↓↓↓
        try:
            api_response =  twitter.get(request_status_url )
        except:
            twitter = OAuth1Session(CK, CS, AT, AS)
            continue
        #↑↑↑↑↑メソッドにしたいところ↑↑↑↑↑
        requests_limit = api_response.headers['x-rate-limit-remaining']#リクエスト可能残数の取得
        print(str(i)+"："+str(requests_limit))
    
[/code]

上記は正常に動作しますが下記のように認証部分メソッドにするとtry文が正常に動作しません。どのようにしたら正常に動くのか、書き方についてアドバイスをいただけたら幸いです。

[code]

    from requests_oauthlib import OAuth1Session
    def request_authorization (request_status_url,CK,CS,AT,AS):
        try:
            api_response = twitter.get(request_status_url)
        except:
            twitter = OAuth1Session(CK,CS,AT,AS)
            api_response = request_authorization(request_status_url)
        return api_response
    CK = "xxxxx" #Consumer key
    CS = "xxxxx" #Consumer secret
    AT = "xxxxx" #Access token
    AS = "xxxxx" #Access token secret
    twitter = OAuth1Session(CK, CS, AT, AS)#認証処理
    request_status_url = 
    "https://api.twitter.com/1.1/statuses/retweets/:id.json"#リクエストURL
    for i in range(3):#適当に３回
        api_response = request_authorization(request_status_url,CK, CS, AT, AS)
        requests_limit = api_response.headers['x-rate-limit-remaining']#リクエスト可能残数の取得
        print(str(i)+"："+str(requests_limit))
    
[/code]

上記のコードを実行した時のエラーコード。

* * *
[code]

    UnboundLocalError                         Traceback (most recent call last)
    <ipython-input-7-25ff3a35d752> in request_authorization(request_status_url, CK, CS, AT, AS)
          3     try:
    ----> 4         api_response = twitter.get(request_status_url)
          5     except:
    
    UnboundLocalError: local variable 'twitter' referenced before assignment
    
    During handling of the above exception, another exception occurred:
    
    TypeError                                 Traceback (most recent call last)
    <ipython-input-7-25ff3a35d752> in <module>()
         15 for i in range(3):#適当に３回
         16     #↓↓↓↓↓メソッドにしたいところ↓↓↓↓↓
    ---> 17     api_response = request_authorization(request_status_url,CK, CS, AT, AS)
         18     #↑↑↑↑↑メソッドにしたいところ↑↑↑↑↑
         19     requests_limit = api_response.headers['x-rate-limit-remaining']#リクエスト可能残数の取得
    
    <ipython-input-7-25ff3a35d752> in request_authorization(request_status_url, CK, CS, AT, AS)
          5     except:
          6         twitter = OAuth1Session(CK,CS,AT,AS)
    ----> 7         api_response = request_authorization(request_status_url)
          8     return api_response
          9 CK = "yGWfCjVCS4uFHRA4q08RIWM2u" #Consumer key
    
    TypeError: request_authorization() missing 4 required positional arguments: 'CK', 'CS', 'AT', and 'AS'
    
[/code]

* * *

ちなみになぜOAuth認証が一回だけでないのかというと、APIからの大量の値の取得を行い、実行が数時間に及んだ時、OAuth認証が切れる時があるからです。認証が切れた時のエラーコードは以下です。

[code]

    Traceback (most recent call last):
    〜〜
    〜〜
    ConnectionResetError: [Errno 54] Connection reset by peer
    During handling of the above exception, another exception occurred:
    
[/code]


CC BY-SA 3.0
2018-03-07T09:52:20.560
42198
2018-03-19T14:25:17.957
2018-03-07T20:57:34.480
24284
26843
question
python python3 twitter oauth
python メソッド内で例外処理を行う方法


なんでエラーになるかだけを回答します。

[code]

    TypeError: request_authorization() missing 4 required positional arguments: 'CK', 'CS', 'AT', and 'AS'
    
[/code]

これは request_authorization関数に 引数 CK, CS, AT, ASが足りないという意味です。

[code]

    def request_authorization (request_status_url,CK,CS,AT,AS):
        try:
            api_response = twitter.get(request_status_url)
        except:
            twitter = OAuth1Session(CK,CS,AT,AS) # <= ローカル変数twitterに代入してるだけ
            api_response = request_authorization(request_status_url) # <= 引数がない
        return api_response
    
[/code]

これで エラーは回避できますが、そもそもこのコードは `rate-limit に到達した時にTwitterのOAuthSessionを作り直す`
をことを全くしてくれません。

なので以下のようにすると良いかと思います。

  * TwitterのOAuthSession を作るのもrequest_authorizationの中でやる
  * except: ではなく rate_limit の場合の例外の場合だけ再帰的に request_authorizationを呼ぶ


CC BY-SA 3.0
2018-03-19T14:25:17.957
42500
2018-03-19T14:25:17.957
2168
42198
answer