2016-09-30 7 views
0

私はこのdocからPythonデコレータを理解しようとしています。 API Exceptionsを処理するために必要な自分のデコレータを作成していました。パラメータ付きデコレータのパラメータへのアクセス

私のデコレータでは、カスタムデコレータ内で引数(methodapidata)にアクセスする方法がありません。

私が知っている通り、私はどこに行っても私はデコレータで受け入れることができないので、どこにでもmethodを渡していません。ここで

は私のデコレータです:

import requests as r 
import json 
def handle_api_exceptions(http_api_call): 
    """ """ 

    def wrapper(*args, **kwargs): 
     """ """ 
     response = {} 
     try: 
      response = http_api_call(*args, **kwargs) 
      if response.ok: 
       result = response.json() 
       if result.get('code', 200) in INVALID_STATUS_CODES: #INVALID_STATUS_CODES = [1801, 1803, 1806,... ] 
        response = {"data":{}, "status":False} 
       else: 
        return result 
      else: 
       capture_failed_requests(method, api, data, response, 
            error=None, reason=response.reason) 
       return {} 
     except r.exceptions.ConnectionError as e: 
      capture_failed_requests(method, api, data, response, error=e, 
             reason="Connection Aborted") 
      return {} 
     except json.decoder.JSONDecodeError as e: 
      capture_failed_requests(method, api, data, response, error=e, 
             reason="Invalid Response") 
      return {} 
     except r.exceptions.ReadTimeout as e: 
      capture_failed_requests(method, api, data, response, error=e, 
             reason="Request Timed Out") 
      return {} 
     except Exception as e: 
      capture_failed_requests(method, api, data, response, error=e, 
             reason="Internal Server Error") 
     return {} 
    return wrapper 

カスタムGET、POSTのAPIリクエスト:

@handle_api_exceptions 
def get(self, api, data, token=None): 
    """ """ 
    if token:data.update(self.get_token(token)) 
    response = r.get(api, data, verify=self.config.SSL_VERIFY, 
         timeout=self.config.REQUEST_TIMEOUT) 
    return response 

@handle_api_exceptions 
def post(self, api, data, token=None): 
    """ """ 
    if token: 
     data.update(self.get_secret_token(token)) 
    response = r.post(api, data, verify=self.config.SSL_VERIFY, 
         timeout=self.config.REQUEST_TIMEOUT) 
    return response   


def post_call(self): 
    """ """ 
    api = "http://192.168.0.24/api/v1/reset/" 
    data = {"k1":[], "k2":{}, "id":123456} #-- Some Key val 
    return self.post(api, data, token="SOME_SECRET_TOKEN") 

クエリは次のとおりです。methodapi、およびcapture_failed_requests()dataを渡す方法は?

+0

現在書かれているように 'method'を渡すことはできませんが、' data'と 'api'は' args'の中にあります。 – jonrsharpe

+0

@jonrsharpe:どこからでもハードコーディングされたメソッド= "GET"またはメソッド= "POST"を渡すことはできますか? – Laxmikant

+0

はい、それをデコレータに直接渡すことができます: '@handle_api_exceptions(method = 'GET')'。心に留めて:http://stackoverflow.com/q/5929107/3001761 – jonrsharpe

答えて

2

dataおよびapiは、argsの内側wrapperである。 methodあなたは別途提供する必要があります。 (例えば、python decorators with parametersを参照してください)。したがって、次のようにこれを行うことができます:

def handle_api_exceptions(method): 
    def decorator(http_api_call): 
     def wrapper(api, data, *args, **kwargs): 
      ... 

あなたの飾り付けは次のようになります。

@handle_api_exceptions(method='GET') 
def get(self, api, data, token=None): 
    ... 

また、あなたは(あなたの'get'を与えるだろう)method = http_api_call.__name__を使用し、メソッド名のネスティングと重複の余分な層を避けることができます。私は空のドキュメンテーション文字列を削除した


注 - いずれかの書き込み、実際のdocstring(私はGoogle-styleを好きですが、メーリングリストへ)か、まったくものを持っていません。あなたの糸くずのルールドキュメントストリングが必要な場合は、それを設定する人は有用なのものを書こうと思っているからです。

+0

ありがとう、私は今それを得た。また、もう1つのGoogleスタイルの提案、感謝した:) – Laxmikant

関連する問題