使用说明
MCP API文档自动化系统
通过自动分析Django REST Framework ViewSet,生成OpenAPI 3.0规范的API文档的完全自动化系统。
📋 目录
🎯 项目概述
目的
- 自动检测和分析Django项目的ViewSet
- 根据实际serializer字段生成准确的OpenAPI 3.0规范
- 完全自动化请求/响应参数、标题和主体信息
- 通过Swagger UI提供直观的API文档
关键特性
- ✅ 完全自动化:自动检测ViewSet,无需手动设置
- ✅ 正确的模式:实际serializer字段1:1反映
- ✅ 125个端点:支持所有ViewSet CRUD操作
- ✅ 实时生成:更改代码时立即更新文档
- ✅ JavaScript兼容:完全支持Swagger UI
🏗️ 系统体系结构
┌─────────────────┐ HTTP Request ┌─────────────────┐
│ MCP Server │ ──────────────────► │ Python Parser │
│ (Spring Boot) │ │ (FastAPI) │
│ Port: 8080 │ │ Port: 8009 │
└─────────────────┘ └─────────────────┘
│ │
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Swagger UI │ │ Django Project │
│ API Docs HTML │ │ ViewSet Files │
│ /api-docs/html │ │ /shared_repos/ │
└─────────────────┘ └─────────────────┘
元件说明
-
Python解析器(FastAPI)
- Django ViewSet自动检测和分析
- 创建OpenAPI 3.0规范
- 提取实际serializer字段
-
MCP服务器(春季启动)
- 提供Swagger UI
- 提供JSON API文档服务
- 代理角色
-
Django项目
- 分析的ViewSet文件
- 实际serializer定义
🚀 主要功能
1.自动检测ViewSet
app/扫描目录中的所有应用程序views.py或者views/分析文件夹中的文件class \w+ViewSet自动发现模式
2.提取Serializer字段
serializer_class自动检测属性- 提取实际字段类型、nullable和required信息
- 嵌套serializer支持
3.创建OpenAPI 3.0规范
- 请求参数(查询、标题、主体)
- 响应模式(按状态代码)
- 认证信息(Authorization标头)
- 分页、搜索、过滤지원
4.自动创建CRUD端点
- 获取
/api/v1/{resource}/-查看列表 - 发布
/api/v1/{resource}/-创建 - 获取
/api/v1/{resource}/{id}/-详细查询 - 放
/api/v1/{resource}/{id}/-修改 - 删除
/api/v1/{resource}/{id}/-删除
🛠️ 技术堆栈
后端
- Python 3.12.2:主解析逻辑
- 快速 API:Python解析器서버
- 姜戈:分析项目
- Django REST框架:ViewSet分析
前端
- Spring Boot:MCP服务器
- Swagger用户界面:API文档接口
- 百里香叶:HTML模板
开发工具
- Gradle:Spring Boot版本
- 优维康:FastAPI服务器
- watch文件:自动重新加载
📁 项目结构
mcp-docs-server-final/
├── python-parser/ # Python Parser 서버
│ ├── main.py # FastAPI 서버 진입점
│ ├── src/
│ │ ├── application/ # 애플리케이션 레이어
│ │ │ └── use_cases/
│ │ │ └── generate_api_docs_use_case.py
│ │ ├── domain/ # 도메인 레이어
│ │ │ └── entities/
│ │ │ ├── api_documentation.py
│ │ │ ├── api_endpoint.py
│ │ │ └── api_parameter.py
│ │ ├── infrastructure/ # 인프라 레이어
│ │ │ ├── generators/
│ │ │ │ └── api_documentation_generator.py
│ │ │ └── parsers/
│ │ │ └── python_parser.py
│ │ └── presentation/ # 프레젠테이션 레이어
│ │ └── controllers/
│ │ └── api_docs_controller.py
│ ├── generated_docs/ # 생성된 API 문서
│ │ └── ucms-be_api_docs.json
│ └── requirements.txt
├── shared_repos/ # 분석 대상 Django 프로젝트
│ └── ucms-be/
│ └── app/
│ ├── account/
│ ├── revenue/
│ ├── content/
│ └── ... (기타 앱들)
├── src/ # Spring Boot MCP 서버
│ └── main/
│ ├── java/
│ │ └── com/odk/
│ │ └── controller/
│ │ └── ApiDocsController.java
│ └── resources/
│ ├── templates/
│ │ └── swagger-viewer.html
│ └── static/
│ └── openapi/
├── build.gradle # Spring Boot 빌드 설정
└── docker-compose.override.yml # Docker 설정
🔧 本地首选参数
1.设置Python环境
# Python 3.12.2 설치 (pyenv 사용)
pyenv install 3.12.2
pyenv local 3.12.2
# 가상환경 생성 및 활성화
cd python-parser
python -m venv venv
source venv/bin/activate # macOS/Linux
# 또는
venv\Scripts\activate # Windows
2.安装Python依赖性
cd python-parser
pip install -r requirements.txt
3.Spring Boot首选参数
# Java 17 이상 필요
java -version
# Gradle 빌드
./gradlew build
🚀 执行方法
1.启动Python Parser服务器
cd python-parser
python main.py
服务器信息:
- 网址:
http://localhost:8009 - 自动重新加载:启用
- Django环境:自动设置
2.启动Spring Boot MCP服务器
# 프로젝트 루트에서
./gradlew bootRun
服务器信息:
- 网址:
http://localhost:8080 - Swagger用户界面:
http://localhost:8080/api-docs/html - JSON API:
http://localhost:8080/api-docs/json
3.生成API文档
# Python Parser 서버가 실행 중인 상태에서
curl -X POST "http://localhost:8009/api/v1/docs/generate/ucms-be?base_url=http://localhost:8009&save_to_file=true"
📖 API使用
1.API文档生成端点
POST /api/v1/docs/generate/{project_name}
参数:
project_name:项目名称(例如ucms-be)base_url:默认URL(例如:http://localhost:8009)save_to_file:是否保存文件(true/false)
回复:
{
"success": true,
"message": "API documentation generated successfully",
"data": {
"endpoints_count": 125,
"file_path": "generated_docs/ucms-be_api_docs.json"
}
}
2.确认生成的文档
- Swagger用户界面:
http://localhost:8080/api-docs/html - JSON文件:
http://localhost:8080/api-docs/json - 本地文件:
python-parser/generated_docs/ucms-be_api_docs.json
🔍 实施详细信息
1.ViewSet自动检测逻辑
def discover_viewsets(django_app_path: str) -> List[Tuple[str, str]]:
"""
Django 앱 디렉토리에서 ViewSet 클래스 자동 탐지
Args:
django_app_path: Django 앱 경로
Returns:
List[Tuple[앱명.ViewSet명, URL경로]]
"""
viewsets = []
# app/ 디렉토리 내 모든 앱 스캔
for app_dir in os.listdir(django_app_path):
app_path = os.path.join(django_app_path, app_dir)
if os.path.isdir(app_path):
# views.py 파일 확인
views_file = os.path.join(app_path, "views.py")
if os.path.exists(views_file):
viewsets.extend(extract_viewsets_from_file(views_file, app_dir))
# views/ 폴더 확인
views_dir = os.path.join(app_path, "views")
if os.path.isdir(views_dir):
for file in os.listdir(views_dir):
if file.endswith(".py"):
file_path = os.path.join(views_dir, file)
viewsets.extend(extract_viewsets_from_file(file_path, f"{app_dir}/views/{file[:-3]}"))
return viewsets
2.Serializer字段提取逻辑
def extract_serializer_from_viewset(viewset_class, viewset_name: str) -> Dict[str, Any]:
"""
ViewSet에서 실제 사용하는 serializer 필드 추출
Args:
viewset_class: ViewSet 클래스
viewset_name: ViewSet 이름
Returns:
Dict[str, Any]: 필드 정보 딕셔너리
"""
try:
# 1. serializer_class 속성 확인
if hasattr(viewset_class, 'serializer_class'):
serializer_class = viewset_class.serializer_class
return extract_serializer_fields(serializer_class)
# 2. get_serializer_class 메서드 확인
if hasattr(viewset_class, 'get_serializer_class'):
serializer_class = viewset_class.get_serializer_class()
return extract_serializer_fields(serializer_class)
# 3. 소스 코드 분석으로 serializer 패턴 찾기
return extract_serializer_from_source(viewset_class, viewset_name)
except Exception as e:
print(f"[문서 자동화] {viewset_name}에서 serializer 필드 추출 실패: {e}")
return None
3.OpenAPI规范生成逻辑
def generate_openapi_for_viewset(
viewset_name: str,
file_path: str,
base_url: str,
model_name: str = None,
) -> List[ApiEndpoint]:
"""
ViewSet에서 OpenAPI 엔드포인트 생성
Args:
viewset_name: ViewSet 클래스명
file_path: ViewSet 파일 경로
base_url: 기본 URL
model_name: 모델명 (선택사항)
Returns:
List[ApiEndpoint]: 생성된 엔드포인트 목록
"""
# 1. ViewSet 클래스 import
viewset_class = import_viewset_class(file_path, viewset_name)
# 2. Serializer 필드 추출
serializer_fields = extract_serializer_from_viewset(viewset_class, viewset_name)
# 3. URL 경로 생성
resource_name = model_name or viewset_name.replace('ViewSet', '').lower()
base_path = f"/api/v1/{resource_name}/"
# 4. CRUD 엔드포인트 생성
endpoints = []
# GET /api/v1/{resource}/ - 목록 조회
endpoints.append(ApiEndpoint(
path=base_path,
method=HttpMethod.GET,
summary=f"Get {resource_name} list",
description=f"Retrieve a list of {resource_name}",
parameters=generate_list_parameters(),
responses=generate_list_responses(serializer_fields)
))
# POST /api/v1/{resource}/ - 생성
endpoints.append(ApiEndpoint(
path=base_path,
method=HttpMethod.POST,
summary=f"Create {resource_name}",
description=f"Create a new {resource_name}",
parameters=generate_create_parameters(),
request_body=generate_request_body(serializer_fields),
responses=generate_create_responses(serializer_fields)
))
# 기타 CRUD 엔드포인트들...
return endpoints
🧪 测试方法
1.测试单位
cd python-parser
python -m pytest tests/
2.集成测试
# 1. Python Parser 서버 시작
cd python-parser
python main.py
# 2. API 문서 생성 요청
curl -X POST "http://localhost:8009/api/v1/docs/generate/ucms-be?base_url=http://localhost:8009&save_to_file=true"
# 3. 생성된 파일 확인
ls -la generated_docs/
cat generated_docs/ucms-be_api_docs.json | jq '.paths | keys | length'
3.测试Swagger UI
# 1. Spring Boot 서버 시작
./gradlew bootRun
# 2. 브라우저에서 확인
open http://localhost:8080/api-docs/html
4.按端点进行测试
# Revenue API 테스트
curl -X GET "http://localhost:8080/api-docs/json" | jq '.paths | keys | grep revenue'
# AdminUser API 테스트
curl -X GET "http://localhost:8080/api-docs/json" | jq '.paths | keys | grep adminuser'
📊 生成的API文档示例
1.Revenue API端点
{
"/api/v1/revenues/": {
"get": {
"summary": "Get revenues list",
"description": "Retrieve a list of revenues",
"tags": ["revenue"],
"parameters": [
{
"name": "Authorization",
"in": "header",
"required": true,
"description": "Bearer token for authentication",
"schema": { "type": "string" }
},
{
"name": "page",
"in": "query",
"required": false,
"description": "Page number for pagination",
"schema": { "type": "integer" }
}
],
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"amount": { "type": "number", "format": "decimal" },
"currency": { "type": "string" },
"created_at": { "type": "string", "format": "date-time" },
"updated_at": { "type": "string", "format": "date-time" }
}
}
}
}
}
}
}
}
}
2.生成的端点统计数据
- 终端合计数量:125个
- ViewSet计数:25个
- 主要ViewSet:
- Revenue(16个字段)
- RevenueShare(16个字段)
- AdminUser(8个字段)
- UserActionHistory(12个字段)
- VideoSource(23个字段)
- Series(18个字段)
- Content(各种字段)
- 所有其他ViewSet
🔧 故障射击
1.Django环境设置问题
问题: DJANGO_SETTINGS_MODULE 未设置
Error: No module named 'django'
解决方案:
def setup_django_environment(django_app_path: str):
"""Django 환경 설정"""
import os
import sys
import django
# Django 설정 모듈 환경변수 설정
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
# 프로젝트 및 앱 경로를 Python 경로에 추가
project_root = os.path.dirname(django_app_path)
sys.path.insert(0, project_root)
sys.path.insert(0, django_app_path)
# Django 설정
django.setup()
2.ViewSet Import失败
问题:相对import错误
Error: attempted relative import with no known parent package
解决方案:
def import_viewset_class(file_path: str, viewset_name: str):
"""ViewSet 클래스 import"""
try:
# 1. 직접 import 시도
module_name = get_module_name_from_path(file_path)
module = importlib.import_module(module_name)
return getattr(module, viewset_name)
except ImportError:
# 2. fallback: 파일 파싱
return parse_viewset_from_file(file_path, viewset_name)
3.提取Serializer字段失败
问题: cached_property 错误
Error: 'cached_property' object has no attribute 'get_fields'
解决方案:
def extract_serializer_fields(serializer_class):
"""Serializer 필드 추출"""
try:
# Serializer 인스턴스 생성
serializer = serializer_class()
# fields 속성에 안전하게 접근
if hasattr(serializer, 'fields'):
fields = serializer.fields
return {name: extract_field_schema(field) for name, field in fields.items()}
except Exception as e:
print(f"Serializer 필드 추출 실패: {e}")
return None
4.JavaScript兼容性问题
问题:在Swagger UI中 Object.keys() 错误
TypeError: Cannot convert undefined or null to object
解决方案:
def to_openapi_dict(self) -> Dict[str, Any]:
"""OpenAPI 3.0 형식으로 변환"""
endpoint_dict = {
"summary": endpoint.summary,
"description": endpoint.description,
"tags": endpoint.tags,
"deprecated": endpoint.deprecated,
"parameters": [...],
}
# null 값 제거로 JavaScript 호환성 확보
if endpoint.request_body is not None:
endpoint_dict["requestBody"] = endpoint.request_body
if endpoint.responses is not None:
endpoint_dict["responses"] = endpoint.responses
return endpoint_dict
📈 性能优化
1.缓存策略
- ViewSet类import结果缓存
- 缓存Serializer字段提取结果
- 通过检测文件更改部分更新
2.并行处理
- 同时分析多个ViewSet
- 文件I/O异步处理
3.内存优化
- 避免创建不必要的对象
- 优化垃圾收集
🔮 未来改进计划
1.功能扩展
- []支持创建GraphQL模式
- []API版本控制
- []支持自定义筛选/排序
- []自动生成API测试代码
2.改善性能
- []引入Redis缓存
- []优化批处理
- []监控内存使用情况
3.提高可用性
- []添加Web界面
- []实时文档更新
- []API文档版本控制
📞 支持和联系
有关项目的问题或错误报告请通过热点问题提交。
开发者:人工智能助理
上次更新:2024年12月
版本: 1.0.0