实现全部 CHOICE 财务接口, 补充测试/文档/部署配置
- 新增 9 个抓取模块: 三大报表/盈利能力/资本结构/营运能力/成长能力/杜邦/分红 - api.py 新增 10 个 /fin/* 接口并统一无数据返回 - 新增 _emchoice.py 共享请求辅助 (emws 跳转取 URL / datacenter 报表拉取) - 新增冒烟测试 tests/test_interfaces.py (24 用例) - 新增接口文档 api_manual.md 与施工蓝图 blueprint.md - 新增 Dockerfile / docker-compose.yml / deploy.sh 部署配置
This commit is contained in:
@@ -0,0 +1,279 @@
|
||||
# EMWeb API 接口文档
|
||||
|
||||
> 东方财富 CHOICE 数据抓取服务 HTTP 接口使用说明。对应目前已实现的功能,随版本更新。
|
||||
|
||||
## 基本信息
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 服务名称 | EMWeb API |
|
||||
| 版本 | 0.1.0 |
|
||||
| 默认地址 | `http://127.0.0.1:8765` |
|
||||
| 数据源 | 东方财富 CHOICE 公开接口(无需登录/cookie) |
|
||||
| Swagger | `http://127.0.0.1:8765/docs` |
|
||||
|
||||
启动:
|
||||
|
||||
```bash
|
||||
uv run python api.py # 监听 0.0.0.0:8765
|
||||
```
|
||||
|
||||
## 通用说明
|
||||
|
||||
### 返回结构
|
||||
|
||||
所有 `/fin/*` 接口成功时返回统一结构:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"count": 10,
|
||||
"columns": ["SECUCODE", "REPORT_DATE", "..."],
|
||||
"data": [ { "SECUCODE": "603233.SH", "..." }, "..." ],
|
||||
"codes_requested": ["603233.SH"],
|
||||
"years": 3
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 说明 |
|
||||
|---|---|
|
||||
| `success` | 是否成功 |
|
||||
| `count` | 数据行数 |
|
||||
| `columns` | 数据列名(与上游接口返回一致,不做翻译) |
|
||||
| `data` | 数据行数组;空值/NaN/NaT/±inf 统一转 `null` |
|
||||
| 其余字段 | 回显本次请求参数,便于排查 |
|
||||
|
||||
### 错误
|
||||
|
||||
| HTTP 状态 | 场景 |
|
||||
|---|---|
|
||||
| `400` | 参数不合法(如 `stocks` 为空) |
|
||||
| `404` | 请求成功但无数据(`success: false`,`data: []`) |
|
||||
| `5xx` | 上游接口异常(超时、返回失败等) |
|
||||
|
||||
### 股票代码格式
|
||||
|
||||
统一使用 `代码.市场`,如 `603233.SH`(上交所)/ `000001.SZ`(深交所)。多只股票用英文逗号分隔。
|
||||
|
||||
---
|
||||
|
||||
## 1. GET /health — 健康检查
|
||||
|
||||
**参数**:无
|
||||
|
||||
**响应**:
|
||||
|
||||
```json
|
||||
{ "status": "ok" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. GET /fin/summary — 财务摘要(报告期)
|
||||
|
||||
拉取多只股票的财务摘要指标(报告期口径,单季度数据请用 `/fin/quarterly-summary`)。
|
||||
|
||||
**参数**
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| `stocks` | string | ✅ | — | 逗号分隔股票列表。两种写法:① 仅代码 `603233.SH`(自动查 ORG_CODE,不稳定);② `代码:ORG_CODE`,如 `603233.SH:10500736`(推荐,最稳) |
|
||||
| `years` | int | | `10` | 拉取多少年历史(1~20) |
|
||||
| `date_type_codes` | string | | `1,5,6` | 报告期代码,逗号分隔:`1`=一季报,`5`=中报,`6`=年报 |
|
||||
| `is_newest` | bool | | `true` | 是否只要最新合并报表 |
|
||||
|
||||
**示例**
|
||||
|
||||
```bash
|
||||
curl "http://127.0.0.1:8765/fin/summary?stocks=603233.SH:10500736&years=5&date_type_codes=1,5,6"
|
||||
```
|
||||
|
||||
**说明**
|
||||
|
||||
- ORG_CODE 无法从公开接口稳定自动获取,推荐在抓包时记录(如大参林 `603233.SH` → `10500736`)。
|
||||
- 只传代码时自动查询失败会返回 `400` 并提示改用 `代码:ORG_CODE` 格式。
|
||||
|
||||
---
|
||||
|
||||
## 3. GET /fin/quarterly-summary — 财务摘要(单季度)
|
||||
|
||||
拉取多只股票的季度财务摘要,数据按 `SECUCODE + REPORT_DATE` 去重并倒序排列。
|
||||
|
||||
**参数**
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH,600519.SH`。仅需代码,不需要 ORG_CODE |
|
||||
| `years` | int | | `3` | 未传 `report_dates` 时,拉取最近多少年的季度数据(1~20) |
|
||||
| `report_dates` | string | | 无 | 可选,逗号分隔的报告期 `YYYY-MM-DD`,如 `2025-03-31,2024-12-31`;传入时精确筛选 |
|
||||
|
||||
**示例**
|
||||
|
||||
```bash
|
||||
# 最近 3 年全部季度
|
||||
curl "http://127.0.0.1:8765/fin/quarterly-summary?stocks=603233.SH&years=3"
|
||||
|
||||
# 精确指定报告期
|
||||
curl "http://127.0.0.1:8765/fin/quarterly-summary?stocks=603233.SH&report_dates=2025-03-31,2024-12-31"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. GET /fin/main-business — 主营构成(按产品 / 按地区)
|
||||
|
||||
拉取多只股票的主营构成,可分别按产品分类或按地区分类。
|
||||
|
||||
**参数**
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH`。仅需代码,不需要 ORG_CODE |
|
||||
| `classify_type` | string | | `产品` | 分类方式:`产品` 或 `地区` |
|
||||
| `years` | int | | `3` | 拉取最近多少年数据(1~20) |
|
||||
|
||||
**示例**
|
||||
|
||||
```bash
|
||||
# 按产品分类(中文参数建议 URL 编码:产品=%E4%BA%A7%E5%93%81)
|
||||
curl "http://127.0.0.1:8765/fin/main-business?stocks=603233.SH&classify_type=%E4%BA%A7%E5%93%81&years=3"
|
||||
|
||||
# 按地区分类(地区=%E5%9C%B0%E5%8C%BA)
|
||||
curl "http://127.0.0.1:8765/fin/main-business?stocks=603233.SH&classify_type=%E5%9C%B0%E5%8C%BA&years=3"
|
||||
```
|
||||
|
||||
**返回数据常见列**
|
||||
|
||||
| 列名 | 说明 |
|
||||
|---|---|
|
||||
| `SECUCODE` | 股票代码 |
|
||||
| `CLASSIFY_TYPE` | 分类方式(产品/地区) |
|
||||
| `STD_REPORT_NAME` | 分类名(如产品名/地区名,含"合计"行) |
|
||||
| `ReportDate` | 报告期(`YYYY-MM-DD HH:MM:SS`) |
|
||||
| `MAIN_BUSINESS_INCOME` | 主营业务收入 |
|
||||
| `MAIN_BUSINESS_COST` | 主营业务成本 |
|
||||
| `MAIN_BUSINESS_RPOFIT` | 主营业务利润 |
|
||||
| `GROSS_RPOFIT_RATIO` | 毛利率(%) |
|
||||
| `MBI_RATIO` | 占主营业务收入比(%) |
|
||||
| `MBR_RATIO` | 占主营业务利润比(%) |
|
||||
| `IS_MAXREPORTDATE` | 是否最新报告期(`1`=是) |
|
||||
|
||||
---
|
||||
|
||||
## 5. 财务报表(资产负债表 / 利润表 / 现金流量表)
|
||||
|
||||
**公共参数**
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH`。仅需代码,不需要 ORG_CODE |
|
||||
| `years` | int | | `3` | 拉取最近多少年的数据(1~20) |
|
||||
|
||||
**示例**
|
||||
|
||||
```bash
|
||||
# 资产负债表
|
||||
curl "http://127.0.0.1:8765/fin/balance?stocks=603233.SH&years=3"
|
||||
|
||||
# 利润表
|
||||
curl "http://127.0.0.1:8765/fin/income?stocks=603233.SH&years=3"
|
||||
|
||||
# 现金流量表
|
||||
curl "http://127.0.0.1:8765/fin/cashflow?stocks=603233.SH&years=3"
|
||||
```
|
||||
|
||||
**说明**:数据为按报告期的明细科目,列数较多(资产负债表约 160+ 列,利润表约 80+ 列,现金流量表约 140 列),列名与上游接口一致(如 `TOTAL_ASSETS`、`TOTAL_OPERATE_INCOME`、`SALES_SERVICES`)。
|
||||
|
||||
---
|
||||
|
||||
## 6. 财务分析指标(盈利能力 / 资本结构 / 营运能力 / 成长能力 / 杜邦)
|
||||
|
||||
**公共参数**
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH`。仅需代码,不需要 ORG_CODE |
|
||||
| `years` | int | | `3` | 拉取最近多少年的数据(1~20) |
|
||||
|
||||
**示例**
|
||||
|
||||
```bash
|
||||
# 盈利能力与收益质量 (ROE/ROA/毛利率等)
|
||||
curl "http://127.0.0.1:8765/fin/profitability?stocks=603233.SH&years=3"
|
||||
|
||||
# 资本结构与偿债能力 (资产负债率/流动比率等)
|
||||
curl "http://127.0.0.1:8765/fin/capital-structure?stocks=603233.SH&years=3"
|
||||
|
||||
# 营运能力 (周转天数/周转率等)
|
||||
curl "http://127.0.0.1:8765/fin/operate-ability?stocks=603233.SH&years=3"
|
||||
|
||||
# 成长能力 (营收/净利同比等)
|
||||
curl "http://127.0.0.1:8765/fin/growth?stocks=603233.SH&years=3"
|
||||
|
||||
# 杜邦分析 (ROE 拆解)
|
||||
curl "http://127.0.0.1:8765/fin/dupont?stocks=603233.SH&years=3"
|
||||
```
|
||||
|
||||
**各接口常见列**
|
||||
|
||||
| 接口 | 常见列 |
|
||||
|---|---|
|
||||
| 盈利能力 | `ROE_AVERAGE`(平均净资产收益率)、`ROE_DILUTED`(摊薄)、`ROA`、`ROIC`、`SALE_GPR`(毛利率)等 |
|
||||
| 资本结构 | `DEBT_ASSET_RATIO`(资产负债率)、`CURRENT_RATIO`(流动比率)、`SPEED_RATIO`(速动比率)等 |
|
||||
| 营运能力 | `OPERATE_CYCLE`(营业周期)、`INVENTORY_DAYS`(存货周转天数)、`ACCOUNTS_RECE_DAYS` 等 |
|
||||
| 成长能力 | `BASICEPS_YOY`、`TOTAL_OPERATEINCOME_YOY`(营收同比)、`PARENT_NETPROFIT_YOY`(净利同比)等 |
|
||||
| 杜邦 | `ROE`、`NETPROFIT`、`TOTAL_ASSETS`、`EQUITY_MULTIPLIER`(权益乘数)、`NETPROFIT_TOI` 等 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 分红(明细 / 统计)
|
||||
|
||||
**公共参数**
|
||||
|
||||
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
||||
|---|---|---|---|---|
|
||||
| `stocks` | string | ✅ | — | 逗号分隔股票代码,如 `603233.SH`。仅需代码,不需要 ORG_CODE |
|
||||
| `years` | int | | `5` | 拉取最近多少年的分红数据(1~20) |
|
||||
|
||||
**示例**
|
||||
|
||||
```bash
|
||||
# 分红明细 (含方案/股权登记日/除权除息日等)
|
||||
curl "http://127.0.0.1:8765/fin/dividend-detail?stocks=603233.SH&years=5"
|
||||
|
||||
# 分红统计 (按年汇总, 含股息率/分红率等)
|
||||
curl "http://127.0.0.1:8765/fin/dividend-statics?stocks=603233.SH&years=5"
|
||||
```
|
||||
|
||||
**各接口常见列**
|
||||
|
||||
| 接口 | 常见列 |
|
||||
|---|---|
|
||||
| 分红明细 | `IMPL_PLAN_PROFILE`(方案)、`ASSIGN_PROGRESS`(进度)、`PRETAX_BONUS_RMB`(每股税前)、`EX_DIVIDEND_DATE`(除权除息日)、`PAY_CASH_DATE` 等 |
|
||||
| 分红统计 | `AUALACCMDIV_ARD`(每股股利)、`PARENTNETPROFIT`、`GXL`(股息率)、`SUM_AUALACCMDIV_ARD` 等 |
|
||||
|
||||
---
|
||||
|
||||
## 接口一览
|
||||
|
||||
| 路径 | 功能 | 数据来源报表 |
|
||||
|---|---|---|
|
||||
| `/health` | 健康检查 | — |
|
||||
| `/fin/summary` | 财务摘要(报告期) | `RPT_CUSTOM_ORGF9_FIN_SUMMARY` |
|
||||
| `/fin/quarterly-summary` | 财务摘要(单季度) | `RPT_HSF9_FIN_SUMMARYQUARTERNEW` |
|
||||
| `/fin/main-business` | 主营构成(产品/地区) | `ZYGC_AFLZS` → `RPT_HSF9_FN_MAINOPBUSINESS` |
|
||||
| `/fin/balance` | 资产负债表 | `CWSJ_ZCFZB` → `RPT_CUSTOM_HSF9_FINA_GBALANCE` |
|
||||
| `/fin/income` | 利润表 | `CWSJ_LRB` → `RPT_CUSTOM_HSF9_FINA_GINCOMESYN` |
|
||||
| `/fin/cashflow` | 现金流量表 | `CWSJ_XJLLB` → `RPT_CUSTOM_HSF9_FINA_GCASHFLOW` |
|
||||
| `/fin/profitability` | 盈利能力与收益质量 | `CWFX_YLNLYSYZL` → `RPT_HSF9_FINA_PROFITEARNING` |
|
||||
| `/fin/capital-structure` | 资本结构与偿债能力 | `CWFX_ZBJGYCZNL` → `RPT_HSF9_FINA_CAPPAYAB` |
|
||||
| `/fin/operate-ability` | 营运能力 | `RPT_HSF9_FINA_OPERATEABILITY` |
|
||||
| `/fin/growth` | 成长能力 | `CWFX_CZNL` → `RPT_HSF9_FINA_GROWTH` |
|
||||
| `/fin/dupont` | 杜邦分析 | `RPT_HSF9_FINA_DUPONT` |
|
||||
| `/fin/dividend-detail` | 分红明细 | `RPT_HSF9_ASSIGNPLAN_DETAIL` |
|
||||
| `/fin/dividend-statics` | 分红统计 | `RPT_HSF9_ASSIGNPLAN_STATICS` |
|
||||
|
||||
## 测试
|
||||
|
||||
```bash
|
||||
uv run pytest tests/ -q # 冒烟测试: 连真实接口验证各模块能取到数据
|
||||
```
|
||||
@@ -0,0 +1,121 @@
|
||||
# EMWeb API 项目施工蓝图
|
||||
|
||||
> 记录项目目标、架构、接口清单、实施进度与施工规范,避免"做到一半忘记当初的规划"。
|
||||
|
||||
---
|
||||
|
||||
## 1. 项目简介
|
||||
|
||||
**目标**:以东方财富 CHOICE 数据接口为基础,封装一套稳定、可复用的财务数据抓取服务,对外以 FastAPI 提供 HTTP 接口。
|
||||
|
||||
**核心诉求**:
|
||||
- 不需要登录 / cookie,直接调公开接口即可拿到数据
|
||||
- 每个数据模块独立成文件,可脚本直接调用,也可通过 API 暴露
|
||||
- 数据以 pandas DataFrame 为内部统一载体,出 HTTP 时转 JSON-safe 结构
|
||||
|
||||
**技术栈**:Python >= 3.11 · FastAPI + Uvicorn · requests · pandas · uv 管理依赖
|
||||
|
||||
---
|
||||
|
||||
## 2. 架构总览
|
||||
|
||||
```
|
||||
EMWebApi/
|
||||
├── api.py # FastAPI 入口, 聚合各 utils 模块对外暴露 HTTP 接口
|
||||
├── utils/
|
||||
│ ├── fin_summary.py # 财务摘要(报告期) —— 最底层, 含共享常量/SSL修复
|
||||
│ ├── _emchoice.py # 内部共享请求辅助 (emws 跳转取 URL / datacenter 报表拉取)
|
||||
│ ├── fin_quarterly.py # 财务摘要(单季度)
|
||||
│ ├── fin_main_business.py # 主营构成(按产品/地区)
|
||||
│ ├── fin_balance.py # 资产负债表
|
||||
│ ├── fin_income.py # 利润表
|
||||
│ ├── fin_cashflow.py # 现金流量表
|
||||
│ ├── fin_profitability.py # 盈利能力与收益质量
|
||||
│ ├── fin_capital_structure.py # 资本结构与偿债能力
|
||||
│ ├── fin_operate.py # 营运能力
|
||||
│ ├── fin_growth.py # 成长能力
|
||||
│ ├── fin_dupont.py # 杜邦分析
|
||||
│ └── fin_dividend.py # 分红明细 + 分红统计
|
||||
├── tests/
|
||||
│ └── test_interfaces.py # 冒烟测试 (连真实接口)
|
||||
└── docs/
|
||||
├── api_docs.md # 从 Reqable 抓包沉淀的原始接口记录
|
||||
├── api_manual.md # 对外 HTTP 接口使用文档
|
||||
└── blueprint.md # 本文件: 施工蓝图
|
||||
```
|
||||
|
||||
**依赖方向**:
|
||||
- `fin_quarterly.py` / `fin_main_business.py` 复用 `fin_summary.py` 里的 `HEADERS` / `TIMEOUT` / `BASE_URL`(顺带触发其模块级的 SSL 自动修复)
|
||||
- 其余 9 个新模块复用 `_emchoice.py` 的 `get_data_url` / `fetch_report`(同样会触发 SSL 修复)
|
||||
|
||||
---
|
||||
|
||||
## 3. 数据源接口清单(源自 docs/api_docs.md)
|
||||
|
||||
| # | 接口 | 报表名/路径 | 实现状态 |
|
||||
|---|------|-------------|----------|
|
||||
| 1 | 财务摘要(单季度) | `RPT_HSF9_FIN_SUMMARYQUARTERNEW` | ✅ 已实现 |
|
||||
| 2 | 主营构成(产品/地区) | `ZYGC_AFLZS` → `RPT_HSF9_FN_MAINOPBUSINESS` | ✅ 已实现 |
|
||||
| 3 | 资产负债表 | `CWSJ_ZCFZB` → `RPT_CUSTOM_HSF9_FINA_GBALANCE` | ✅ 已实现 |
|
||||
| 4 | 利润表 | `CWSJ_LRB` → `RPT_CUSTOM_HSF9_FINA_GINCOMESYN` | ✅ 已实现 |
|
||||
| 5 | 现金流量表 | `CWSJ_XJLLB` → `RPT_CUSTOM_HSF9_FINA_GCASHFLOW` | ✅ 已实现 |
|
||||
| 6 | 盈利能力与收益质量 | `CWFX_YLNLYSYZL` → `RPT_HSF9_FINA_PROFITEARNING` | ✅ 已实现 |
|
||||
| 7 | 资本结构与偿债能力 | `CWFX_ZBJGYCZNL` → `RPT_HSF9_FINA_CAPPAYAB` | ✅ 已实现 |
|
||||
| 8 | 营运能力 | `RPT_HSF9_FINA_OPERATEABILITY` | ✅ 已实现 |
|
||||
| 9 | 成长能力 | `CWFX_CZNL` → `RPT_HSF9_FINA_GROWTH` | ✅ 已实现 |
|
||||
| 10 | 杜邦分析 | `RPT_HSF9_FINA_DUPONT` | ✅ 已实现 |
|
||||
| 11 | 分红明细 + 分红统计 | `RPT_HSF9_ASSIGNPLAN_DETAIL` / `_STATICS` | ✅ 已实现 |
|
||||
|
||||
**文档外补充**:财务摘要(报告期) 用 `RPT_CUSTOM_ORGF9_FIN_SUMMARY`,需 ORG_CODE(不在 api_docs.md 里)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 实施进度
|
||||
|
||||
### ✅ 已完成(11 类接口全部落地)
|
||||
|
||||
| 功能 | 核心文件 | HTTP 接口 |
|
||||
|------|----------|-----------|
|
||||
| 财务摘要(报告期) | `utils/fin_summary.py` | `GET /fin/summary` |
|
||||
| 财务摘要(单季度) | `utils/fin_quarterly.py` | `GET /fin/quarterly-summary` |
|
||||
| 主营构成(产品/地区) | `utils/fin_main_business.py` | `GET /fin/main-business` |
|
||||
| 资产负债表 | `utils/fin_balance.py` | `GET /fin/balance` |
|
||||
| 利润表 | `utils/fin_income.py` | `GET /fin/income` |
|
||||
| 现金流量表 | `utils/fin_cashflow.py` | `GET /fin/cashflow` |
|
||||
| 盈利能力与收益质量 | `utils/fin_profitability.py` | `GET /fin/profitability` |
|
||||
| 资本结构与偿债能力 | `utils/fin_capital_structure.py` | `GET /fin/capital-structure` |
|
||||
| 营运能力 | `utils/fin_operate.py` | `GET /fin/operate-ability` |
|
||||
| 成长能力 | `utils/fin_growth.py` | `GET /fin/growth` |
|
||||
| 杜邦分析 | `utils/fin_dupont.py` | `GET /fin/dupont` |
|
||||
| 分红明细 + 统计 | `utils/fin_dividend.py` | `GET /fin/dividend-detail` / `dividend-statics` |
|
||||
| 测试 | `tests/test_interfaces.py` | `uv run pytest tests/ -q` (24 用例) |
|
||||
|
||||
### 🧹 待清理
|
||||
|
||||
- `fin_summary.py` 里的 `_debug_report`(向 `127.0.0.1:7777/event` 发 POST)是调试残留,可移除
|
||||
- `_auto_fix_ssl` 里残留 Windows 路径(`%USERPROFILE%\...`),运行环境是 macOS,可精简
|
||||
|
||||
---
|
||||
|
||||
## 5. 施工规范(新模块必须遵守)
|
||||
|
||||
1. **文件命名**:`utils/fin_<主题>.py`,一个主题一个文件,内部函数私有化(`_` 开头);仅内部共享的请求辅助放 `utils/_emchoice.py`
|
||||
2. **结构**:`_build_*(参数构造)` → `_fetch_one(单只拉取)` → `get_<主题>(批量主入口)`
|
||||
3. **共享**:`from utils.fin_summary import HEADERS, TIMEOUT`,不重复定义;不同 base_url 的接口在本文件内定义新常量;emws 跳转接口用 `_emchoice.get_data_url`,datacenter 报表用 `_emchoice.fetch_report`
|
||||
4. **数据流**:内部统一 `pandas.DataFrame`,每行冗余 `SECUCODE` 列便于多股票合并
|
||||
5. **校验**:`payload.get("success")` 失败抛 `RuntimeError`;空数据返回空 DataFrame 而非报错
|
||||
6. **接口暴露**:api.py 中新增 `GET /fin/<主题>`,参数用 FastAPI `Query`,返回 `{success, count, columns, data, errors}` 风格,NaN/NaT/inf 转 None(复用 `_df_to_json_payload`),无数据统一走 `_empty_response`
|
||||
7. **礼貌抓取**:批量循环中加随机延时(参考 `SLEEP_RANGE`)
|
||||
8. **注释语言**:中文,解释"为什么"(如接口编码映射差异)
|
||||
9. **测试**:新模块在 `tests/test_interfaces.py` 注册冒烟用例(连真实接口取 1 年数据,断言非空 + 关键列)
|
||||
|
||||
---
|
||||
|
||||
## 6. 常用命令
|
||||
|
||||
```bash
|
||||
uv sync # 创建环境并安装依赖
|
||||
uv run python api.py # 启动服务 (默认端口 8765)
|
||||
uv run pytest tests/ -q # 跑冒烟测试 (连真实接口)
|
||||
uv run python -c "..." # 直接跑脚本
|
||||
```
|
||||
Reference in New Issue
Block a user