#!/usr/bin/env python # -*- encoding: utf-8 -*- """ @Version: 1.0 @Python Version:3.6.6 @Author: ludq1 @Email: ludq1@chinaunicom.cn @date: 2023/04/07 11:40:00 @Description: """ import logging from typing import Optional, List from .app_exception import AppException from .base_const import ConstResponseCode from .common_app_config import CommonAppConfig class UtilMethods: @classmethod def get_intvalue_from_dict_and_check_range( cls, source_dict: dict, key_name: str, min_value: Optional[int] = None, max_value: Optional[int] = None, other_allowed_values: List[int] = None, action_desc: str = None, check_null: bool = True, default_value: int = 0, ) -> int: r""" 从字典中获取指定key的值,并检查其是否是int,并检查其值的范围 :param source_dict: :param key_name: :param min_value:可选值,提供则判断最小值, :param max_value:可选值 :param other_allowed_values: 允许的值范围,例如 [-1], 在此范围内则不校验 最小/最大值 :param action_desc: 抛出异常时的描述 :param check_null: 默认为True,即值为None是抛出异常 :param default_value: 默认值, None表示0 """ action_desc = action_desc or "从字典中获取字符串值" if not key_name: result = source_dict else: result = source_dict.get(key_name) if result is None: if check_null: if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时未提供{key_name}" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result})为空" ) else: result = default_value if default_value is not None else 0 if not isinstance(result, int): if key_name: raise AppException( code=ConstResponseCode.CODE_SYS_ERROR, message=f"{action_desc}时未提供{key_name},使用默认值 {result},但不是int类型" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result})为空,使用默认值 {result},但不是int类型" ) elif not isinstance(result, int): if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时{key_name}不是int类型" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result})不是int类型" ) if other_allowed_values and result in other_allowed_values: return result if min_value is not None and result < min_value: if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时{key_name}的值小于{min_value}" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result})小于{min_value}" ) if max_value is not None and result > max_value: if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时{key_name}的值大于{max_value}" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result})大于{max_value}" ) return result @classmethod def get_strvalue_from_dict( cls, source_dict: dict, key_name: str, check_null_or_empty: bool = True, default_value: str = None, action_desc: str = None ) -> str: r""" 从字典获取字符串, :param source_dict: :param key_name: :param check_null_or_empty:是否检查值是否为空或null,默认为True :param default_value: 默认值,默认为空字符串 :param action_desc: 抛出异常时的描述 """ if not key_name: result_obj = source_dict else: result_obj = source_dict.get(key_name) if result_obj is not None: result_obj = f"{result_obj}" if check_null_or_empty and not result_obj: if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时未提供{key_name}" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据为空" ) return result_obj or default_value or "" @classmethod def get_boolvalue_from_dict( cls, source_dict: dict, key_name: str, check_null: bool = True, default_value: bool = False, action_desc: str = None ) -> bool: r""" 从字典获取bool值, 注意 default_value 是 None 时, 默认值为 None :param source_dict: :param key_name: :param check_null:是否检查值是否为空或null,默认为True :param default_value: 默认值,默认为 False :param action_desc: 抛出异常时的描述 """ if not key_name: result_obj = source_dict else: result_obj = source_dict.get(key_name) if result_obj is None: if check_null: if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时未提供{key_name}" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result_obj})为None" ) else: result_obj = default_value if not isinstance(result_obj, bool): if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时{key_name}不是bool类型" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result_obj})不是bool类型" ) return result_obj @classmethod def get_objvalue_from_dict( cls, source_dict: dict, key_name: str, obj_class, action_desc: str = None, check_null: bool = True, **kwargs ): r""" 从字典获取对象, :param source_dict: :param key_name: :param obj_class: :param action_desc: :param check_null: :param kwargs: """ if not key_name: result_obj = source_dict else: result_obj = source_dict.get(key_name) if isinstance(result_obj, obj_class): return result_obj elif isinstance(result_obj, dict): kwargs.update(result_obj) return obj_class().init_by_create_dict(**kwargs) elif result_obj is None: if check_null: if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时未提供{key_name}" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result_obj})为空" ) else: return None else: if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时{key_name}为不支持的类型" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result_obj})为不支持的类型" ) @classmethod def get_enumvalue_from_dict( cls, source_dict: dict, key_name: str, obj_class, action_desc: str = None, logger: logging.Logger = None, check_null: bool = True, default_value=None, ): r""" 从字典获取枚举类型对象 :param source_dict: :param key_name: :param obj_class :param action_desc: :param logger: :param check_null: :param default_value: """ logger = logger or CommonAppConfig().common_logger if not key_name: result_obj = source_dict else: result_obj = source_dict.get(key_name) if isinstance(result_obj, obj_class): return result_obj elif result_obj is None: if check_null: if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时未提供{key_name}" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result_obj})为None" ) else: return default_value else: try: return obj_class(str(result_obj)) except BaseException as e: encountered_e = e if encountered_e: logger.error(encountered_e) if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时{key_name}不是有效的{obj_class.__name__}值类型" ).with_traceback(encountered_e.__traceback__) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({result_obj})不是有效的{obj_class.__name__}值类型" ).with_traceback(encountered_e.__traceback__) @classmethod def get_listvalue_from_dict( cls, source_dict: dict, key_name: str, obj_class, check_null: bool = False, action_desc: str = None ) -> list: r""" 从字典获取列表, :param source_dict: :param key_name: :param obj_class :param check_null: 默认为False :param action_desc: """ if not key_name: tmp_key_value = source_dict else: tmp_key_value = source_dict.get(key_name) if not tmp_key_value: if check_null: if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时未提供{key_name}" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据为空" ) else: return list() if not isinstance(tmp_key_value, list): if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时提供{key_name}不是列表" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({tmp_key_value})不是列表" ) result_obj = list() for tmp_obj in tmp_key_value: if isinstance(tmp_obj, obj_class): result_obj.append(tmp_obj) elif isinstance(tmp_obj, dict): result_obj.append(obj_class().init_by_create_dict(**tmp_obj)) else: if key_name: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时{key_name}中的对象是不支持的类型" ) else: raise AppException( code=ConstResponseCode.CODE_MISSING_PARAMETER, message=f"{action_desc}时源数据({tmp_key_value})中的对象是不支持的类型" ) return result_obj