Files
TJWaterServerBinary/scripts/generate_openapi_markdown.py
T

81 lines
2.6 KiB
Python

import argparse
from pathlib import Path
import sys
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from app.main import app
HTTP_METHODS = ("get", "post", "put", "patch", "delete", "options", "head")
def _parameter_line(parameter: dict) -> str:
required = "必填" if parameter.get("required") else "可选"
description = parameter.get("description")
suffix = f" {description}" if description else ""
return (
f" - `{parameter.get('name', '-')}` "
f"({parameter.get('in', '-')}, {required}){suffix}"
)
def build_markdown() -> str:
schema = app.openapi()
info = schema.get("info", {})
lines = [
"# TJWater Server API 文档",
"",
"本文档根据后端服务 OpenAPI 配置生成,用于查看接口路径、方法和用途。",
"",
"## 基本信息",
"",
f"- 标题:{info.get('title', '')}",
f"- 版本:{info.get('version', '')}",
f"- 描述:{info.get('description', '')}",
"",
"## 接口列表",
"",
]
for path in sorted(schema.get("paths", {})):
path_item = schema["paths"][path]
for method in HTTP_METHODS:
operation = path_item.get(method)
if not operation:
continue
lines.extend(
[
f"### `{method.upper()} {path}`",
"",
f"- 分组:{', '.join(operation.get('tags', [])) or '-'}",
f"- 说明:{operation.get('summary', '')}",
]
)
if operation.get("description"):
lines.append(f"- 详情:{operation['description'].strip()}")
parameters = operation.get("parameters", [])
if parameters:
lines.append("- 参数:")
lines.extend(_parameter_line(parameter) for parameter in parameters)
if operation.get("requestBody"):
lines.append("- 请求体:需要")
response_codes = ", ".join(operation.get("responses", {}).keys())
lines.extend([f"- 响应状态:{response_codes}", ""])
return "\n".join(lines).rstrip() + "\n"
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("outputs", nargs="+", type=Path)
args = parser.parse_args()
content = build_markdown()
for output in args.outputs:
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(content, encoding="utf-8")
print(output)
if __name__ == "__main__":
main()