从 Redfish 接口文档(Word .docx 或纯文本 .txt)中提取接口清单与接口参数,
方便后续做跨版本 / 跨产品(如 BMC vs PoDM)的对比分析。
日常使用先看:Redfish 接口对比快速说明。
基础
.docx提取逻辑仅用 Python 3 标准库(zipfile+xml.etree)直读, 不需要pandoc/python-docx。 baseline 对比、Excel 读写和 YAML 读取需要openpyxl与PyYAML。
同一份 docx 里,参数在两个地方各出现一次:参数表 和 请求/响应示例代码。 两个地方互为校验——理想情况下应一致,不一致就是文档 bug。所以仓库里有 两个独立的提取脚本,字段和输出结构完全对称,便于 diff:
| 路径 | 数据源 | 脚本 |
|---|---|---|
| 表格路径 | "请求参数 / 响应参数" 小节里的参数表 | scripts/extract_from_tables.py |
| 示例路径 | "请求示例 / 响应示例" 小节里的 HTTP 报文和 JSON | scripts/extract_from_examples.py |
两条路径的实现彼此独立(比如 marker 识别规则不同——示例里有 "请求示例 1 / 响应示例 2" 这种带空格数字后缀的写法;表格没有)。互不共享状态,一边优化不会影响另一边。
PoDM/
├── README.md
├── .gitignore
├── pyproject.toml
├── scripts/
│ ├── _docx_utils.py # 共享 .docx 读取 (跳 ToC + 合成 X.Y.Z 编号)
│ ├── _defaults.py # 默认文档名 / data-output-analysis 路径
│ ├── _interface_list.py # 接口清单 YAML 输出
│ ├── extract_podm_interface_list.py # PoDM:提取接口清单(不含参数)
│ ├── extract_bmc_interface_list.py # BMC:提取接口清单(不含参数)
│ ├── extract_from_tables.py # 路径①:从表格提取 URI + 参数 (同时产出 uris.txt)
│ ├── extract_from_examples.py # 路径②:从示例代码提取 URI + 参数 (同时产出 uris.txt)
│ ├── extract_bmc.py # BMC:提取接口 + 参数
│ ├── extract_cmcc.py # 中国移动要求文档:提取 URI + 参数
│ ├── extract_cmcc_interface_list.py # 中国移动要求文档:提取接口清单(不含参数)
│ ├── extract_cmcc_toc.py # 中国移动要求文档:单独提取章节目录
│ ├── run_podm_bmc_pipeline.py # 一键跑 PoDManager vs BMC 提取流水线
│ ├── compare_podm_bmc_to_baseline.py # PoDManager vs BMC baseline 对比
│ ├── promote_podm_bmc_baseline.py # 将人工复核 PoDManager vs BMC Excel 提升为 baseline
│ ├── extract_podm_resource_tree_interface_list.py # PoDM:从 Redfish 资源树表提取接口清单
│ ├── compare_podm_resource_tree_to_baseline.py # PoDManager vs 资源树 baseline 对比
│ ├── promote_podm_resource_tree_baseline.py # 将人工复核资源树 Excel 提升为 baseline
│ ├── run_pipeline.py / update_* / promote_* # 旧命名兼容 wrapper
│ ├── check.py # 编译 + 单元测试
│ ├── docx_to_text.py # 诊断/协作:把 .docx 转成保留表格 Tab 的纯文本
│ ├── col_enum.py # 诊断:按列索引枚举表格某列取值
│ ├── type_enum.py # 诊断:枚举参数表"类型"列的取值
│ ├── docx_diag.py # 诊断:打印段落样式分布
│ └── section_dump.py # 诊断:导出指定章节的原文
├── analysis/ # 一次性对比分析 (BMC vs PoDM)
│ ├── error_cases.md / .docx
│ ├── cross_doc_diff.md / .docx
│ └── why_missing_classification.md
├── baseline/ # 当前人工确认后的接口对比基线
│ ├── podm_bmc/
│ │ ├── baseline.xlsx
│ │ ├── manifest.json
│ │ └── backups/
│ └── podm_resource_tree/
│ ├── baseline.xlsx
│ ├── manifest.json
│ └── backups/
├── .codex/skills/ # 项目本地 Codex skill
│ ├── podm-bmc-compare
│ ├── podm-bmc-promote
│ ├── podm-tree-compare
│ └── podm-tree-promote
├── data/ # 原始文档(.docx / .txt),不入库
├── output/ # 脚本生成的结果,不入库
└── tests/ # 标准库 unittest 冒烟测试
data/ 与 output/ 目录只保留空壳(.gitkeep),内部文件默认被 .gitignore 屏蔽。
本项目现在按两类任务管理:
- 提取接口清单:只输出
index / section / title / method / uri,不含参数。 - 提取接口 + 参数:输出接口元数据和
path/header/body/query/response参数。
| 脚本 | 作用 | 默认输出 |
|---|---|---|
scripts/extract_podm_interface_list.py |
PoDManager:提取接口清单(index/section/title/method/uri,不含参数) | <PoDM stem>.interface-list.yaml |
scripts/extract_bmc_interface_list.py |
BMC:提取接口清单(index/section/title/method/uri,不含参数) | <BMC stem>.interface-list.yaml |
scripts/extract_from_tables.py |
表格路径:从参数表抽 URI + path/header/body/query/response | <input>.interfaces.yaml + <input>.uris.txt |
scripts/extract_from_examples.py |
示例路径:从请求/响应示例代码抽相同字段结构 | <input>.example.interfaces.yaml + <input>.example.uris.txt |
scripts/extract_bmc.py |
BMC:从命令格式 / 输出说明抽 URI + 参数 | <input>.bmc.interfaces.yaml + <input>.bmc.uris.txt |
scripts/extract_cmcc_interface_list.py |
中国移动要求文档:从命令格式抽接口清单(index/section/title/method/uri,不含参数) | output/20260610/cmcc.interface-list.yaml |
scripts/extract_cmcc.py |
中国移动要求文档:从命令格式 / 参数说明 / 输出说明抽 URI + path/header/body/query/response 参数 | output/20260610/cmcc.interfaces.yaml + output/20260610/cmcc.uris.txt |
scripts/extract_cmcc_toc.py |
中国移动要求文档:单独抽 6.1.x 章节目录,便于排查 section 丢失/错位 |
output/20260610/cmcc.toc.yaml + output/20260610/cmcc.toc.txt |
scripts/run_podm_bmc_pipeline.py |
一键跑 PoDManager/BMC 接口清单和接口+参数提取 | output/<date>/podm.interface-list.yaml、output/<date>/bmc.interface-list.yaml |
scripts/compare_podm_bmc_to_baseline.py |
PoDManager 接口清单与 BMC 接口清单对比;存在 baseline 时标注新增/删除/变更 | output/<date>/analysis/podm_bmc_summary.xlsx |
scripts/promote_podm_bmc_baseline.py |
将人工复核后的 PoDManager vs BMC 对比 Excel 提升为 baseline | baseline/podm_bmc/baseline.xlsx |
scripts/extract_podm_resource_tree_interface_list.py |
从 PoDManager "Redfish资源树"表提取接口;GET/PATCH、GET/POST、GET/DELETE、GET/PATCH/DELETE 等会拆成多条 method+URI;空"允许操作"单元格按 Word 纵向合并表格规则继承上一条非空操作 |
output/<date>/podm.resource-tree.interface-list.yaml |
scripts/compare_podm_resource_tree_to_baseline.py |
资源树接口与 PoDManager 接口清单对比;存在资源树 baseline 时标注新增/删除/变更 | output/<date>/analysis/podm_resource_tree_summary.xlsx |
scripts/promote_podm_resource_tree_baseline.py |
将人工复核后的资源树对比 Excel 提升为资源树 baseline | baseline/podm_resource_tree/baseline.xlsx |
把原始文档放到 data/<日期>/,输出落在 output/<日期>/。
一键执行需要传日期参数。脚本会读取 data/<日期>/ 下的固定文件名,并输出到
output/<日期>/:
python3 scripts/run_podm_bmc_pipeline.py 20260507输入文件应为:
data/20260507/Atlas PoDManager 1.0.0 Redfish 接口参考.docx
data/20260507/华为服务器 iBMC300 Redfish 接口说明.docx
输出目录为:
output/20260507/
如需指定非默认文件路径:
python3 scripts/run_podm_bmc_pipeline.py 20260507 \
--podm data/20260507/Atlas PoDManager 1.0.0 Redfish 接口参考.docx \
--bmc data/20260507/华为服务器 iBMC300 Redfish 接口说明.docx单独执行某一步时,不带参数会直接跑默认输入文件:
# 默认输入见 scripts/_defaults.py
python3 scripts/extract_podm_interface_list.py
python3 scripts/extract_bmc_interface_list.py
python3 scripts/extract_from_tables.py
python3 scripts/extract_from_examples.py传参数可处理任何文件:
python3 scripts/extract_podm_interface_list.py data/你的PoDM文件.docx output/你的PoDM文件.interface-list.yaml
python3 scripts/extract_bmc_interface_list.py data/你的BMC文件.docx output/你的BMC文件.interface-list.yaml
python3 scripts/extract_from_tables.py data/你的文件.docx output/你的文件.interfaces.yaml
python3 scripts/extract_from_examples.py data/你的文件.docx output/你的文件.example.interfaces.yaml
python3 scripts/extract_bmc.py data/你的BMC文件.docx output/你的BMC文件.bmc.interfaces.yaml
python3 scripts/extract_cmcc_interface_list.py data/你的中国移动要求文档.docx output/cmcc.interface-list.yaml
python3 scripts/extract_cmcc.py data/你的中国移动要求文档.docx output/cmcc.interfaces.yaml
python3 scripts/extract_cmcc_toc.py data/你的中国移动要求文档.docx output/cmcc.toc.yaml只传输入、不传输出时,结果写到约定的默认文件名。
如果原始 Word 不能直接共享,可先转成提取友好的纯文本再复制给 Codex:
python3 scripts/docx_to_text.py data/你的接口文档.docx
python3 scripts/docx_to_text.py data/你的接口文档.docx -o -默认会生成 data/你的接口文档.extraction.txt。输出中普通段落逐行保留,Word 表格按
"一行一行、单元格用 Tab 分隔" 展开,目录段落会跳过,标题自动编号会尽量合成为 X.Y.Z 标题。
中国移动服务器 Redfish 管理接口要求文档可直接使用以下默认输入路径:
python3 scripts/extract_cmcc_interface_list.py
python3 scripts/extract_cmcc.py默认读取 data/20260610/附件5:中国移动服务器Redfish管理接口要求V6.1.0-v20260604.docx。
如果文档路径不同,也可以按上面的传参方式指定输入和输出。
如果 .docx 直读时丢失或错还原 Word 自动章节号,可在同目录放一份从 Word 直接复制粘贴出来的
纯文本,脚本会优先使用它,再回退到 .docx。推荐文件名是把 .docx 换成 .paste.txt:
data/20260610/附件5:中国移动服务器Redfish管理接口要求V6.1.0-v20260604.docx
data/20260610/附件5:中国移动服务器Redfish管理接口要求V6.1.0-v20260604.paste.txt
也支持同名 .copy.txt / .manual.txt,以及 原文件名.docx.paste.txt
/ 原文件名.docx.copy.txt / 原文件名.docx.manual.txt。这种旁路只对
extract_cmcc*.py 生效,不影响 PoDManager/BMC 提取脚本。
如发现接口提取出的 section 仍然异常,可先单独提取目录核对源文本中的章节号。
对 .docx 输入,目录脚本会读取 Word 标题大纲层级并合成 1 / 5.2.1 / 6.1.3.7.3
这类章节号,同时跳过正文表格;如果同目录存在 .paste.txt / .copy.txt / .manual.txt
旁路文本,则优先使用旁路文本中的显式章节号:
python3 scripts/extract_cmcc_toc.py data/20260610/附件5:中国移动服务器Redfish管理接口要求V6.1.0-v20260604.docx output/20260610/cmcc.toc.yaml脚本会同时写出 cmcc.toc.yaml 和 cmcc.toc.txt,字段包含 section / level / title / line。
资源树接口提取支持直接传日期,脚本会读取 data/<日期>/ 下的 PoDManager 固定文件名,并写到
output/<日期>/:
python3 scripts/extract_podm_resource_tree_interface_list.py 20260609两条接口+参数路径都同时产出 .interfaces.yaml(结构化参数清单)和 .uris.txt
(每行 [METHOD] URI,顺序与 yaml 一致),分别给结构化 diff 和纯 URI
集合对比用。
如果要换默认文件名,改 scripts/_defaults.py 里的 PODM_DOCX_NAME /
BMC_DOCX_NAME 常量即可。
项目内置 4 个独立 skill,安装/启用后可按日期调用:
/podm-bmc-compare 20260609
/podm-bmc-promote 20260609
/podm-tree-compare 20260609
/podm-tree-promote 20260609
podm-bmc-compare调用scripts/run_podm_bmc_pipeline.py,再调用scripts/compare_podm_bmc_to_baseline.py,生成podm_bmc_summary.xlsx和podm_bmc_update_report.json。podm-bmc-promote调用scripts/promote_podm_bmc_baseline.py,把人工审核后的podm_bmc_summary.xlsx更新为baseline/podm_bmc/baseline.xlsx并重算 manifest;旧 baseline 会归档到baseline/podm_bmc/backups/<UTC时间戳>/。podm-tree-compare调用scripts/extract_podm_interface_list.py、scripts/extract_podm_resource_tree_interface_list.py和scripts/compare_podm_resource_tree_to_baseline.py,生成podm_resource_tree_summary.xlsx和podm_resource_tree_update_report.json。资源树表中的多操作行会按 method 拆分,例如GET/PATCH/DELETE计为 3 个接口;空"允许操作"单元格会继承上一条非空操作;该流程不依赖 BMC 文档。podm-tree-promote调用scripts/promote_podm_resource_tree_baseline.py,把人工审核后的podm_resource_tree_summary.xlsx更新为baseline/podm_resource_tree/baseline.xlsx并重算 manifest;旧资源树 baseline 会归档到baseline/podm_resource_tree/backups/<UTC时间戳>/。
scripts/run_pipeline.py、scripts/update_interface_summary_from_baseline.py、scripts/promote_reviewed_baseline.py、scripts/extract_resource_tree_interfaces.py、scripts/update_resource_tree_summary_from_baseline.py、scripts/promote_resource_tree_baseline.py 仍保留为兼容 wrapper,新流程优先使用上面的显式命名脚本。
首次使用 baseline 对比能力前,确保依赖已安装:
python -m pip install -e .提交前跑统一检查:
conda run -n base python scripts/check.py检查内容:
- 编译
scripts/*.py - 运行
tests/下的标准库unittest
interface-list.yaml
interfaces:
- index: 1
section: 3.19.3
title: 基于SPDM协议获取组件签名测量值
method: POST
uri: https://device_ip/redfish/v1/ComponentIntegrity/component_integrity_id/Actions/ComponentIntegrity.SPDMGetSignedMeasurementsinterfaces.yaml
interfaces:
- section: 4.2.25
title: 导出日志信息
method: POST
uri: /redfish/v1/Managers/{manager_id}/LogServices/{logservices_id}/Actions/Oem/Huawei/LogService.ExportLog
params:
path: [manager_id, logservices_id]
header: [X-Auth-Token, Content-Type]
body: [Type, Content]
query: []
response: ["@odata.context", "@odata.type", "@odata.id", Id, Name, TaskState, StartTime, Messages, Oem/Huawei, TaskPercentage]跑完主工作流如果发现某节漏字段 / 多字段 / 解析错乱,按症状对号:
| 症状 | 用哪个 |
|---|---|
| 某节解析不完整,想看原文长啥样 | scripts/section_dump.py X.Y.Z 导出该节扁平化后的原文 |
| 类型词白名单要扩哪些 | scripts/type_enum.py 列出"类型"列所有真实取值 + 频次 |
| 怀疑表格某列写法不一致 | scripts/col_enum.py 1 列出第 2 列所有取值 |
| 标题识别不全 | scripts/docx_diag.py 看段落样式分布 |
脚本按以下规则识别文档结构:
- 章节标题:
数字.数字[.数字...]+ 空格 + 文本,例如4.2.25 导出日志信息 - 接口小节:依次使用中文标记
接口功能/调用方法/URI/请求参数/请求示例/响应参数/响应示例 - 参数表:以
表X-XXX ... 参数列表为标题;表头常见列名含参数名称/必选/类型/参数值域/默认值/参数说明 - 表格行在 Word 导出后以
\t或 2+ 空格分隔;多行单元格的续行自动并入上一行
- 手动序号的标题(Word 自动编号)在文本中没有
X.Y.Z字样时识别不到。 - 嵌套表(表中套表)可能漏行。
- 旧版
.doc(OLE2 二进制)不支持;先用libreoffice --headless --convert-to docx或pandoc转成.docx。
MIT