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.
cbmc/codedetect/scripts/generate-api-docs.py

261 lines
7.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env python3
# CodeDetect API文档生成器
import os
import sys
import re
import inspect
import json
from pathlib import Path
from typing import Dict, List, Any, Optional
from dataclasses import dataclass, asdict
@dataclass
class APIEndpoint:
"""API端点信息"""
method: str
path: str
description: str
parameters: List[Dict[str, Any]]
responses: Dict[str, Any]
auth_required: bool = False
@dataclass
class WebSocketEvent:
"""WebSocket事件信息"""
event_name: str
direction: str # 'send' or 'receive'
description: str
data_structure: Dict[str, Any]
class APIDocGenerator:
"""API文档生成器"""
def __init__(self, source_dir: str = "src"):
self.source_dir = Path(source_dir)
self.output_dir = Path("docs/api")
self.endpoints: List[APIEndpoint] = []
self.websocket_events: List[WebSocketEvent] = []
def generate_all_docs(self):
"""生成所有API文档"""
print("🚀 开始生成API文档...")
# 创建输出目录
self.output_dir.mkdir(parents=True, exist_ok=True)
# 扫描源代码
self._scan_api_endpoints()
self._scan_websocket_events()
# 生成文档
self._generate_rest_api_docs()
self._generate_websocket_docs()
self._generate_openapi_spec()
print("✅ API文档生成完成")
def _scan_api_endpoints(self):
"""扫描API端点"""
api_file = self.source_dir / "ui" / "api.py"
if not api_file.exists():
print(f"⚠️ API文件不存在: {api_file}")
return
print("📡 扫描REST API端点...")
# 简单的端点检测逻辑
content = api_file.read_text()
# 查找路由定义
route_pattern = r'@(\w+)\.route\([\'"]([^\'"]+)[\'"](?:,\s*methods=\[([^\]]+)\])?\)'
matches = re.findall(route_pattern, content)
for decorator, path, methods in matches:
if methods:
method_list = [m.strip().strip('\'"') for m in methods.split(',')]
else:
method_list = ['GET']
for method in method_list:
endpoint = APIEndpoint(
method=method,
path=path,
description=f"{method} {path}",
parameters=[],
responses={"200": {"description": "Success"}}
)
self.endpoints.append(endpoint)
print(f" 发现 {len(self.endpoints)} 个API端点")
def _scan_websocket_events(self):
"""扫描WebSocket事件"""
socketio_file = self.source_dir / "ui" / "socketio_handlers.py"
if not socketio_file.exists():
print(f"⚠️ WebSocket文件不存在: {socketio_file}")
return
print("🔌 扫描WebSocket事件...")
content = socketio_file.read_text()
# 查找事件处理器
event_pattern = r'@socketio\.on\([\'"]([^\'"]+)[\'"]\)'
matches = re.findall(event_pattern, content)
for event_name in matches:
event = WebSocketEvent(
event_name=event_name,
direction="receive",
description=f"WebSocket事件: {event_name}",
data_structure={}
)
self.websocket_events.append(event)
print(f" 发现 {len(self.websocket_events)} 个WebSocket事件")
def _generate_rest_api_docs(self):
"""生成REST API文档"""
doc_content = """# CodeDetect REST API 参考
## 概述
CodeDetect提供RESTful API用于代码验证和突变生成。
## 认证
大多数API端点需要认证。使用Bearer Token格式
```
Authorization: Bearer <your-api-key>
```
## 基础URL
```
http://localhost:5000/api/v1
```
"""
# 按路径分组端点
endpoints_by_path = {}
for endpoint in self.endpoints:
if endpoint.path not in endpoints_by_path:
endpoints_by_path[endpoint.path] = []
endpoints_by_path[endpoint.path].append(endpoint)
# 生成端点文档
for path, path_endpoints in endpoints_by_path.items():
doc_content += f"\n## {path}\n\n"
for endpoint in path_endpoints:
doc_content += f"### {endpoint.method} {path}\n\n"
doc_content += f"{endpoint.description}\n\n"
if endpoint.parameters:
doc_content += "#### 请求参数\n\n"
for param in endpoint.parameters:
doc_content += f"- **{param['name']}** ({param['type']}): {param['description']}\n"
doc_content += "\n"
doc_content += "#### 响应\n\n"
for status, response in endpoint.responses.items():
doc_content += f"**{status}**: {response['description']}\n\n"
doc_content += "---\n\n"
# 写入文件
(self.output_dir / "rest-api.md").write_text(doc_content)
def _generate_websocket_docs(self):
"""生成WebSocket文档"""
doc_content = """# CodeDetect WebSocket API 参考
## 概述
CodeDetect使用WebSocket提供实时更新和进度通知。
## 连接
```javascript
const socket = io('http://localhost:5000');
```
## 事件
"""
# 生成事件文档
for event in self.websocket_events:
doc_content += f"### {event.event_name}\n\n"
doc_content += f"**方向**: {event.direction}\n\n"
doc_content += f"{event.description}\n\n"
if event.data_structure:
doc_content += "#### 数据结构\n\n"
doc_content += "```json\n"
doc_content += json.dumps(event.data_structure, indent=2, ensure_ascii=False)
doc_content += "\n```\n\n"
doc_content += "---\n\n"
# 写入文件
(self.output_dir / "websocket-api.md").write_text(doc_content)
def _generate_openapi_spec(self):
"""生成OpenAPI规范"""
spec = {
"openapi": "3.0.0",
"info": {
"title": "CodeDetect API",
"version": "1.0.0",
"description": "CodeDetect代码验证和突变生成API"
},
"servers": [
{
"url": "http://localhost:5000/api/v1",
"description": "开发服务器"
}
],
"paths": {},
"components": {
"securitySchemes": {
"BearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT"
}
}
}
}
# 添加路径
for endpoint in self.endpoints:
path = endpoint.path
method = endpoint.method.lower()
if path not in spec["paths"]:
spec["paths"][path] = {}
spec["paths"][path][method] = {
"summary": endpoint.description,
"responses": endpoint.responses
}
if endpoint.auth_required:
spec["paths"][path][method]["security"] = [{"BearerAuth": []}]
# 写入文件
(self.output_dir / "openapi.json").write_text(
json.dumps(spec, indent=2, ensure_ascii=False)
)
def main():
"""主函数"""
generator = APIDocGenerator()
generator.generate_all_docs()
if __name__ == "__main__":
main()