50 lines
2.4 KiB
Python
50 lines
2.4 KiB
Python
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 [] |