访问参数化装饰器中的参数

时间:2016-09-30 08:40:32

标签: python python-decorators

我正试图从这个doc了解python decorator。并且正在编写处理API异常所需的自己的装饰器。

但是在我的装饰器中,我没有得到如何在我的自定义装饰器中访问参数(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")

查询是:如何在method中传递apidatacapture_failed_requests()

1 个答案:

答案 0 :(得分:2)

dataapi位于argswrappermethod您必须单独提供,例如通过参数化装饰器(参见例如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):
    ...

或者,你可以使用method = http_api_call.__name__(这会给你'get'),并避免额外的嵌套和方法名重复。

请注意,我删除了空文档字符串 - 要么写一个实际的文档字符串(我喜欢Google-style,而是YMMV),要么根本没有。如果您的linting规则需要 docstrings,那是因为无论是谁设置它都希望您编写有用的,而不仅仅是欺骗它。