feat: Flask API增加asset_type参数支持类型验证

新功能:
- /api/v1/ohlcv 接口新增可选 asset_type 参数
- 用于验证code与指定类型是否匹配
- 类型不匹配时返回400错误并说明

API文档更新:
- endpoints 添加 asset_type 参数说明
- 新增 asset_types 字段说明各类型含义

使用示例:
- /api/v1/ohlcv?code=000300.SH (自动检测)
- /api/v1/ohlcv?code=000300.SH&asset_type=china_index (验证类型)
- /api/v1/ohlcv?code=513100.SH&asset_type=us_index (类型不匹配报错)
This commit is contained in:
2026-05-12 23:32:08 +08:00
parent fb755fc31e
commit 95c7a091f5

View File

@@ -409,13 +409,22 @@ def index():
"info": "/", "info": "/",
"health": "/health", "health": "/health",
"asset_type": "/api/v1/asset-type?code={code}", "asset_type": "/api/v1/asset-type?code={code}",
"ohlcv": "/api/v1/ohlcv?code={code}&start={YYYY-MM-DD}&end={YYYY-MM-DD}", "ohlcv": "/api/v1/ohlcv?code={code}&start={YYYY-MM-DD}&end={YYYY-MM-DD}&asset_type={type}",
"ohlcv_nocache": "/api/v1/ohlcv?code={code}&nocache=true", "ohlcv_nocache": "/api/v1/ohlcv?code={code}&nocache=true",
"ohlcv_asset_type": "/api/v1/ohlcv?code={code}&asset_type=china_index (验证类型)",
"batch": "POST /api/v1/ohlcv/batch", "batch": "POST /api/v1/ohlcv/batch",
"etf_nav": "/api/v1/etf/nav?code={code}", "etf_nav": "/api/v1/etf/nav?code={code}",
"cache_clear": "POST /api/v1/cache/clear", "cache_clear": "POST /api/v1/cache/clear",
"cache_stats": "/api/v1/cache/stats", "cache_stats": "/api/v1/cache/stats",
}, },
"asset_types": {
"china_index": "中国指数 (000300.SH, 399006.SZ等)",
"china_etf": "中国ETF (159915.SZ, 513100.SH等)",
"us_index": "美股指数 (NDX, SPX, N225等)",
"hk_index": "港股指数 (HSI, HSTECH.HK等)",
"futures": "期货 (AU.SHF, CU.SHF等)",
"crypto": "加密货币 (BTC, ETH - 不缓存)",
},
"supported_assets": { "supported_assets": {
"china_index": ["000300.SH", "399006.SZ", "H30269.CSI"], "china_index": ["000300.SH", "399006.SZ", "H30269.CSI"],
"china_etf": ["159915.SZ", "513100.SH", "518880.SH"], "china_etf": ["159915.SZ", "513100.SH", "518880.SH"],
@@ -469,18 +478,27 @@ def get_ohlcv():
code: 标的代码 (required) code: 标的代码 (required)
start: 开始日期 YYYY-MM-DD (optional, 默认90天前) start: 开始日期 YYYY-MM-DD (optional, 默认90天前)
end: 结束日期 YYYY-MM-DD (optional, 默认今天) end: 结束日期 YYYY-MM-DD (optional, 默认今天)
asset_type: 资产类型 (optional, 用于验证或强制指定)
- china_index: 中国指数
- china_etf: 中国ETF
- us_index: 美股指数
- hk_index: 港股指数
- futures: 期货
- crypto: 加密货币
nocache: 是否跳过缓存 (optional, 默认false) nocache: 是否跳过缓存 (optional, 默认false)
""" """
code = request.args.get('code', '').strip() code = request.args.get('code', '').strip()
start = request.args.get('start', '').strip() start = request.args.get('start', '').strip()
end = request.args.get('end', '').strip() end = request.args.get('end', '').strip()
asset_type_param = request.args.get('asset_type', '').strip().lower()
nocache = request.args.get('nocache', 'false').lower() == 'true' nocache = request.args.get('nocache', 'false').lower() == 'true'
# 参数验证 # 参数验证
if not code: if not code:
return jsonify({ return jsonify({
"error": "Missing required parameter: code", "error": "Missing required parameter: code",
"example": "/api/v1/ohlcv?code=000300.SH&start=2024-01-01&end=2024-03-31" "example": "/api/v1/ohlcv?code=000300.SH&start=2024-01-01&end=2024-03-31",
"asset_type_hint": "可选 asset_type 参数强制指定类型",
}), 400 }), 400
# 设置默认日期 # 设置默认日期
@@ -495,13 +513,35 @@ def get_ohlcv():
"end": end, "end": end,
}), 400 }), 400
# 自动检测资产类型
detected_type = AssetTypeDetector.detect(code)
# 如果指定了 asset_type 参数,验证是否匹配
if asset_type_param:
try:
# 将字符串转换为 AssetType
expected_type = AssetType(asset_type_param)
if detected_type != expected_type:
return jsonify({
"error": f"Asset type mismatch",
"code": code,
"detected_type": detected_type.value,
"expected_type": expected_type.value,
"hint": f"代码 {code} 自动检测为 {detected_type.value}, 但指定了 {expected_type.value}",
}), 400
except ValueError:
return jsonify({
"error": f"Invalid asset_type: {asset_type_param}",
"valid_types": [t.value for t in AssetType],
}), 400
# 使用缓存获取数据 # 使用缓存获取数据
result, is_cached = fetch_data_with_ttl(code, start, end, nocache) result, is_cached = fetch_data_with_ttl(code, start, end, nocache)
if result is None: if result is None:
return jsonify({ return jsonify({
"code": code, "code": code,
"asset_type": AssetTypeDetector.detect(code).value, "asset_type": detected_type.value,
"error": "No data available", "error": "No data available",
"start": start, "start": start,
"end": end, "end": end,
@@ -510,11 +550,12 @@ def get_ohlcv():
if "error" in result: if "error" in result:
return jsonify({ return jsonify({
"code": code, "code": code,
"asset_type": AssetTypeDetector.detect(code).value, "asset_type": detected_type.value,
"error": result["error"], "error": result["error"],
}), 500 }), 500
result['cached'] = is_cached result['cached'] = is_cached
result['asset_type'] = detected_type.value # 确保返回类型
return jsonify(result) return jsonify(result)