python参数校验代码

class Code(object):
    MSG = { }
    
    @classmethod
    def api_resp(cls, code=0, msg=None, data=None):
        if codeis None:
            reason = cls.MSG.get(result, '')
        return ApiResp(result, reason, resp)
    
def safe_int(val):
    if isinstance(val, (int, long)):
        return val
    if isinstance(val, basestring):
        val = val.strip()
    try:
        if isinstance(val, basestring) and "." in val:
            return int(float(val))
        return int(val)
    except Exception:
        raise ValidateException(Code.invalid_params, 'safe_int error ,'
                                                     'val:{0}'.format(val))


def safe_float(val):
    if isinstance(val, float):
        return val
    if isinstance(val, (int, long)):
        return float(val)
    if isinstance(val, basestring):
        val = val.strip()
    try:
        return float(val)
    except Exception:
        raise ValidateException(Code.invalid_params, 'safe_float error ,'
                                                     'val:{0}'.format(val))


def safe_str(val, encodeing="utf-8"):
    try:
        if not isinstance(val, basestring):
            return str(val)
        if isinstance(val, unicode):
            return val.encode(encodeing, "replace")
        return val
    except Exception:
        raise ValidateException(Code.invalid_params, 'safe_str error ,'
                                                     'val:{0}'.format(val))


class ArgsTypeConsts(object):
    STR = 'str'
    INT = 'int'
    FLOAT = 'float'
    OBJ = 'object'
    ARRAY = 'array'


class ArgsResolver(object):

    def __init__(self, input_obj, obj_desc):
        '''

        :param input_obj: 输入需要校验的对象
        :param obj_desc:  校验描述对象
        '''
        self.not_null(input_obj, 'input_obj').not_null(obj_desc,
                                                       'obj_desc')
        self.input_obj = input_obj
        self.obj_desc = obj_desc

    def resolve(self):
        return self.resolve_obj(self.input_obj, self.obj_desc)

    def resolve_obj(self, ipt_obj, obj_desc):
        if not obj_desc:
            return ipt_obj
        opt_obj = {}
        for arg_desc in obj_desc:
            name = arg_desc['name']
            val = ipt_obj.get(name)
            val = self.resolve_obj_entry(val, arg_desc)
            opt_obj[name] = val
        return opt_obj

    def not_null(self, val, name='param'):
        if val is None:
            raise ValidateException(Code.invalid_params, '{0} can not be ' \
                                                         'null'.format(name))
        return self

    def ensure_arr(self, val, name='param'):
        if not isinstance(val, (list, set)):
            raise ValidateException(Code.invalid_params,
                                    '{0} should be array:{1}'.format(
                                        name, val))

    def ensure_obj(self, val, name='param'):
        if not isinstance(val, dict):
            raise ValidateException(Code.invalid_params, '{0} should be '
                                                         'object:{1}'.format(
                name, val))

    def resolve_obj_entry(self, key_val, arg_desc):
        name = arg_desc['name']
        _type = arg_desc['type']
        default_val = arg_desc.get('default', None)
        def_required = 'default' not in arg_desc
        required = arg_desc.get('required', def_required)
        # 1.检查 是否必须
        if required:
            self.not_null(key_val, name)
        # 2.检查是否需要设值默认值
        if not required and key_val is None and default_val is not None:
            # 非必须 key_val 为空 配置了 default_val
            key_val = default_val
        # 3. 检查类型
        if key_val is not None:
            if _type == ArgsTypeConsts.STR:
                key_val = safe_str(key_val)
            elif _type == ArgsTypeConsts.INT:
                key_val = safe_int(key_val)
            elif _type == ArgsTypeConsts.FLOAT:
                key_val = safe_float(key_val)
            elif _type == ArgsTypeConsts.OBJ:
                # 确保是对象
                self.ensure_obj(key_val, name)
                object_desc = arg_desc.get('object_desc', None)
                key_val = self.resolve_obj(key_val, object_desc)
            elif _type == ArgsTypeConsts.ARRAY:
                # 确保是数组
                self.ensure_arr(key_val, name)
                array_desc = arg_desc.get('array_desc')
                key_val = self.resolve_arr(key_val, array_desc)
            else:
                raise ValidateException(Code.invalid_params,
                                        'unknow type:{0}'.format(
                                            _type))
        return key_val

    def resolve_arr(self, ipt_arr, arr_desc):
        if not arr_desc:
            return ipt_arr
        opt_arr = []
        _type = arr_desc.get('type')
        for key_val in ipt_arr:
            if _type == ArgsTypeConsts.STR:
                key_val = safe_str(key_val)
                opt_arr.append(key_val)
            elif _type == ArgsTypeConsts.INT:
                key_val = safe_int(key_val)
                opt_arr.append(key_val)
            elif _type == ArgsTypeConsts.FLOAT:
                key_val = safe_float(key_val)
                opt_arr.append(key_val)
            elif _type == ArgsTypeConsts.OBJ:
                # 确保是对象
                self.ensure_obj(key_val)
                object_desc = arr_desc.get('object_desc', None)
                key_val = self.resolve_obj(key_val, object_desc)
                opt_arr.append(key_val)
            elif _type == ArgsTypeConsts.ARRAY:
                # 确保是数组
                self.ensure_arr(key_val)
                array_desc = arr_desc.get('array_desc', None)
                key_val = self.resolve_arr(key_val, array_desc)
                opt_arr.append(key_val)
            else:
                raise ValidateException(Code.invalid_params, 'unknow type:{' \
                                                             '0}'.format(type))

        return opt_arr


if __name__ == '__main__':
    desc = [
        # {'name': 'x', 'type': 'float', 'required': True, },
        {'name': 'y', 'type': 'object', 'required': True,
         'object_desc': [
             {'name': 'a', 'type': 'int', 'required': True},
             {'name': 'b', 'type': 'array', 'required': True,
              'array_desc': {
                  'type': 'str'
              }},
             {'name': 'c', 'type': 'array', 'required': True,
              'array_desc': {
                  'type': 'object',
                  'object_desc': [
                      {'name': 'a', 'type': 'int', 'required': True},
                  ]
              }}
         ]},

    ]
    data = {
        "x": "3.12",
        "y": {
            'a': '1',
            'b': ['1', 2],
            'c': [{'a': '1'}]
        }
    }
    resolver = ArgsResolver(data, desc)
    api_resp = None
    try:
        resolved_data = resolver.resolve()
        api_resp = Code.api_resp(resp=resolved_data)
    except ValidateException as v:
        api_resp = Code.api_resp(v.result, v.reason)
    print 'api_resp===\n', api_resp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值