from typing import Any, List, Optional import logging logger = logging.getLogger(__name__) def extract_data_for_validation(response_json: Any, nested_list_keywords: Optional[List[str]] = None) -> List[Any]: """ 从原始API响应JSON中智能提取需要被验证的核心业务数据列表。 即使只有一个对象,也返回一个单元素的列表。 策略: 1. 如果响应体是包含 'code' 和 'data' 的标准包装,则提取 'data' 的内容。 2. 对上一步的结果,遍历一个关键字列表(nested_list_keywords),检查是否存在分页列表模式,如果存在则提取该列表。 3. 如果处理后的数据是列表,直接返回该列表。 4. 如果处理后的数据是单个对象(字典),将其包装在单元素列表中返回。 5. 如果数据为空或不适用,返回空列表。 """ if nested_list_keywords is None: nested_list_keywords = ["list", "records", "items", "data"] if not response_json: return [] data_to_process = response_json # 策略 1: 解开标准包装 if isinstance(response_json, dict) and 'code' in response_json and 'data' in response_json: logger.debug("检测到标准响应包装,提取 'data' 字段内容进行处理。") data_to_process = response_json['data'] # 策略 2: 提取嵌套的分页列表 if isinstance(data_to_process, dict): for keyword in nested_list_keywords: if keyword in data_to_process and isinstance(data_to_process[keyword], list): logger.debug(f"检测到关键字为 '{keyword}' 的嵌套列表,提取其内容。") data_to_process = data_to_process[keyword] break # 找到第一个匹配的就停止 # 策略 3 & 4: 统一返回列表 if isinstance(data_to_process, list): logger.debug(f"数据本身为列表,包含 {len(data_to_process)} 个元素,直接返回。") return data_to_process if isinstance(data_to_process, dict): logger.debug("数据为单个对象,将其包装在列表中返回。") return [data_to_process] # 策略 5: 对于其他情况(如数据为None或非对象/列表类型),返回空列表 logger.warning(f"待处理的数据既不是列表也不是对象,无法提取进行验证。数据: {str(data_to_process)[:100]}") return []