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()