You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
EMWebApi/docs/blueprint.md

9.5 KiB

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       # 分红明细 + 分红统计
│   ├── fin_free_holders.py   # 十大流通股东
│   ├── fin_holders.py        # 十大股东明细
│   ├── fin_holder_num.py     # 股东户数
│   ├── fin_mda.py            # 管理层讨论与分析(MD&A)
│   ├── fin_equity.py         # 股本结构
│   ├── fin_company.py        # 公司介绍 + 所属行业
│   ├── fin_belong_index.py   # 所属指数分类/统计/成分权重
│   └── fin_major_events.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 自动修复)
  • 其余新模块复用 _emchoice.pyget_data_url / fetch_report(同样会触发 SSL 修复)
  • fin_major_events.py / fin_company.py / fin_belong_index.py 内部有 _run / _fetch_one 复用,避免六接口重复样板

3. 数据源接口清单(源自 docs/api_docs.md)

# 接口 报表名/路径 实现状态
1 财务摘要(单季度) RPT_HSF9_FIN_SUMMARYQUARTERNEW 已实现
2 主营构成(产品/地区) ZYGC_AFLZSRPT_HSF9_FN_MAINOPBUSINESS 已实现
3 资产负债表 CWSJ_ZCFZBRPT_CUSTOM_HSF9_FINA_GBALANCE 已实现
4 利润表 CWSJ_LRBRPT_CUSTOM_HSF9_FINA_GINCOMESYN 已实现
5 现金流量表 CWSJ_XJLLBRPT_CUSTOM_HSF9_FINA_GCASHFLOW 已实现
6 盈利能力与收益质量 CWFX_YLNLYSYZLRPT_HSF9_FINA_PROFITEARNING 已实现
7 资本结构与偿债能力 CWFX_ZBJGYCZNLRPT_HSF9_FINA_CAPPAYAB 已实现
8 营运能力 RPT_HSF9_FINA_OPERATEABILITY 已实现
9 成长能力 CWFX_CZNLRPT_HSF9_FINA_GROWTH 已实现
10 杜邦分析 RPT_HSF9_FINA_DUPONT 已实现
11 分红明细 + 分红统计 RPT_HSF9_ASSIGNPLAN_DETAIL / _STATICS 已实现
12 十大流通股东 RPT_F10_EH_FREEHOLDERS 已实现
13 十大股东明细 RPT_DMSK_HOLDERS 已实现
14 股东户数 RPT_F10_EH_HOLDERNUM 已实现
15 管理层讨论与分析 RPT_BUSINESSANALYSIS 已实现
16 股本结构 RPT_F10_EH_EQUITY 已实现
17 公司介绍 RPT_HSF9_BASIC_ORGINFO 已实现
18 所属行业 RPT_STOCKF9_INDUSTRY 已实现
19 指数分类 RPT_HSF9_BELONGINDEX_CLASSIF 已实现
20 纳入指数统计 RPT_CUSTOM_HSF9_BELONG_INDEX 已实现
21 指数成分权重 RPT_HSF9_BELONG_INDEX 已实现
22 并购事件 RPT_HS_ACQUISITIONS_EVENT 已实现
23 股权激励 RPT_DMSK_SH_EQUITYINCENTIVE 已实现
24 诉讼仲裁 RPT_LITIGATION_ARBITRATION_BSINFO 已实现
25 关联交易 RPT_RELATED_TRANSACTION 已实现
26 违规处罚 RPT_HSF9_OP_VIOLATION 已实现
27 对外担保 RPT_F9_GUARANTEE 已实现

文档外补充:财务摘要(报告期) 用 RPT_CUSTOM_ORGF9_FIN_SUMMARY,需 ORG_CODE(不在 api_docs.md 里)。


4. 实施进度

已完成(api_docs.md 全部 27 项落地)

功能 核心文件 HTTP 接口
健康检查 api.py GET /health
财务摘要(报告期) 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 / GET /fin/dividend-statics
十大流通股东 utils/fin_free_holders.py GET /fin/free-holders
十大股东明细 utils/fin_holders.py GET /fin/holders
股东户数 utils/fin_holder_num.py GET /fin/holder-num
管理层讨论与分析 utils/fin_mda.py GET /fin/mda
股本结构 utils/fin_equity.py GET /fin/equity
公司介绍 utils/fin_company.py GET /fin/company-info
所属行业 utils/fin_company.py GET /fin/industry
指数分类/统计/成分 utils/fin_belong_index.py GET /fin/index-classif / GET /fin/belong-index / GET /fin/index-membership
并购事件 utils/fin_major_events.py GET /fin/acquisitions
股权激励 utils/fin_major_events.py GET /fin/equity-incentive
诉讼仲裁 utils/fin_major_events.py GET /fin/litigation
关联交易 utils/fin_major_events.py GET /fin/related-transaction
违规处罚 utils/fin_major_events.py GET /fin/violation
对外担保 utils/fin_major_events.py GET /fin/guarantee
测试 tests/test_interfaces.py uv run pytest tests/ -q (56 用例)

🧹 待清理

  • 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. 校验fetch_reportsuccess=False 且 message 为"返回数据为空/暂无数据/无数据"时按空结果处理(返回空列表),其余失败抛 RuntimeError;空数据返回空 DataFrame 而非报错
  6. 接口暴露:api.py 中每个接口必须用显式 @app.get 装饰器 + Query 参数(不使用程序化注册),返回 {success, count, columns, data, errors} 风格,NaN/NaT/inf 转 None(复用 _df_to_json_payload),无数据统一走 _empty_response;纯 stocks 参数用 _split_codes 解析
  7. 礼貌抓取:批量循环中加随机延时(参考 SLEEP_RANGE
  8. 注释语言:中文,解释"为什么"(如接口编码映射差异)
  9. 测试:新模块在 tests/test_interfaces.py 注册冒烟用例(连真实接口取 1 年数据,断言非空 + 关键列)

6. 常用命令

uv sync                              # 创建环境并安装依赖
uv run python api.py                 # 启动服务 (默认端口 8765)
uv run pytest tests/ -q              # 跑冒烟测试 (连真实接口)
uv run python -c "..."               # 直接跑脚本