关于 extract-openapi-from-code
这项技能帮助开发者从现有 API 项目中提取 OpenAPI 规范,覆盖 Python、Java、TypeScript、Ruby 和 PHP 的八种框架,并指导后续验证与 SDK 生成。
主要功能
- 01覆盖八种 API 框架
- 02提供框架专属提取方法
- 03执行 OpenAPI 检查与验证
- 04通过 Overlay 修正规范
- 05可选生成 SDK
适用场景
- 01将现有 API 转为 OpenAPI 文档
- 02为代码优先 API 准备 SDK 生成
- 03验证并修正提取的规范
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ speakeasy-api/ sdk-generation-skills --skill extract-openapi-from-code安装后在 Claude Code 中输入/extract-openapi-from-code确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
content/frameworks/django.mdfastapi.mdflask.mdhono.mdlaravel.mdnestjs.mdrails.mdspring-boot.md详细介绍
从代码中提取 OpenAPI
从现有 API 代码库中提取 OpenAPI 规范。涵盖 Python、Java、JavaScript/TypeScript、Ruby 和 PHP 中的八种主流框架。
内容指南
| 框架 | 语言 | 指南 |
|---|---|---|
| FastAPI | Python | content/frameworks/fastapi.md |
| Flask | Python | content/frameworks/flask.md |
| Django REST Framework | Python | content/frameworks/django.md |
| Spring Boot | Java | content/frameworks/spring-boot.md |
| NestJS | TypeScript | content/frameworks/nestjs.md |
| Hono | TypeScript | content/frameworks/hono.md |
| Rails | Ruby | content/frameworks/rails.md |
| Laravel | PHP | content/frameworks/laravel.md |
每份指南都详细介绍了相应框架的设置、架构定义、Speakeasy 扩展、身份验证和故障排查。
适用场景
- 用户已有 API,并希望从中生成 OpenAPI 规范
- 用户希望从尚无 OpenAPI 规范的代码中创建 SDK
- 用户提到了特定框架(FastAPI、Flask、Django、Spring Boot、NestJS、Hono、Rails、Laravel)
- 用户提到:“提取 OpenAPI”、“代码优先”、“从代码生成规范”、“现有 API 代码”
输入
| 输入 | 必需 | 描述 |
|---|---|---|
| 框架 | 是 | 所使用的 API 框架(参见决策框架) |
| 项目路径 | 是 | API 项目的根目录 |
| 输出路径 | 否 | 规范的写入位置(默认为 openapi.json 或 openapi.yaml) |
| 目标语言 | 否 | 提取后生成 SDK 时所用的目标语言 |
输出
| 输出 | 描述 |
|---|---|
| OpenAPI 规范 | 描述 API 的 JSON 或 YAML 文件 |
| 验证报告 | speakeasy lint 的检查结果 |
前提条件
- API 项目必须可构建,且已安装其依赖项
- 对于运行时提取(FastAPI、Spring Boot、NestJS、Hono),应用必须可导入或可启动
- 已安装
speakeasyCLI,以便在提取后进行验证和 SDK 生成
决策框架
使用此表确定提取方法:
| 框架 | 语言 | 方法 | 是否需要运行服务? |
|---|---|---|---|
| FastAPI | Python | 内置导出 | 否 |
| Flask (flask-smorest) | Python | CLI 命令 | 否 |
| Django REST Framework | Python | drf-spectacular CLI | 否 |
| Spring Boot (springdoc) | Java | HTTP 端点 | 是 |
| NestJS | TypeScript | HTTP 端点或脚本 | 是 |
| Hono (zod-openapi) | TypeScript | 编程式导出 | 否 |
| Rails (rswag) | Ruby | Rake 任务 | 否 |
| Laravel (l5-swagger) | PHP | Artisan 命令 | 否 |
命令
在下方选择与你的框架对应的命令。提取后,务必使用 speakeasy lint 进行验证。
Python:FastAPI
FastAPI 会在运行时生成 OpenAPI 架构。无需启动服务即可导出:
python -c "import json; from myapp import app; print(json.dumps(app.openapi()))" > openapi.json
将 myapp 替换为包含 FastAPI app 实例的模块名称。如果应用采用工厂模式:
python -c "import json; from myapp import create_app; app = create_app(); print(json.dumps(app.openapi()))" > openapi.json
你也可以启动服务,然后从 http://localhost:8000/openapi.json 获取规范。
Python:Flask (flask-smorest)
需要安装 flask-smorest 或 apispec:
flask openapi write openapi.json
如果直接使用 apispec,可通过编程方式导出:
import json
from myapp import create_app, spec
app = create_app()
with app.app_context():
print(json.dumps(spec.to_dict()))
Python:Django REST Framework
需要安装 drf-spectacular:
python manage.py spectacular --file openapi.yaml
要输出 JSON:
python manage.py spectacular --format openapi-json --file openapi.json
Java:Spring Boot
需要安装 springdoc-openapi。启动应用,然后获取规范:
# Start the app (background)
./mvnw spring-boot:run &
# Wait for startup
sleep 15
# Fetch the spec
curl http://localhost:8080/v3/api-docs -o openapi.json
# For YAML format
curl http://localhost:8080/v3/api-docs.yaml -o openapi.yaml
# Stop the app
kill %1
如果服务运行在不同的端口或上下文路径,请相应调整 URL。
TypeScript:NestJS
需要 @nestjs/swagger。启动应用,然后获取:
# Start the app (background)
npm run start &
sleep 10
# Fetch the spec (default path with SwaggerModule)
curl http://localhost:3000/api-json -o openapi.json
# Stop the app
kill %1
或者,创建一个脚本,在不运行服务器的情况下导出:
// scripts/export-openapi.ts
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from '../src/app.module';
import * as fs from 'fs';
async function bootstrap() {
const app = await NestFactory.create(AppModule, { logger: false });
const config = new DocumentBuilder().setTitle('API').build();
const doc = SwaggerModule.createDocument(app, config);
fs.writeFileSync('openapi.json', JSON.stringify(doc, null, 2));
await app.close();
}
bootstrap();
TypeScript:Hono (zod-openapi)
需要 @hono/zod-openapi。以编程方式导出架构:
// scripts/export-openapi.ts
import { app } from '../src/app';
import * as fs from 'fs';
const doc = app.doc('/doc', {
openapi: '3.1.0',
info: { title: 'API', version: '1.0.0' },
});
fs.writeFileSync('openapi.json', JSON.stringify(doc, null, 2));
运行:
npx tsx scripts/export-openapi.ts
Ruby:Rails (rswag)
需要 rswag:
rails rswag:specs:swaggerize
默认情况下,规范会写入 swagger/v1/swagger.yaml(可在 config/initializers/rswag_api.rb 中配置)。
PHP:Laravel (l5-swagger)
需要 l5-swagger:
php artisan l5-swagger:generate
默认情况下,规范会写入 storage/api-docs/api-docs.json。
提取后的步骤
提取规范后,务必执行以下步骤:
1. 验证规范
speakeasy lint openapi --non-interactive -s openapi.json
2. 使用 overlays 修复问题(如有需要)
如果验证发现问题,请使用 overlay,而不要直接修改提取出的规范:
speakeasy overlay apply -s openapi.json -o fixes.yaml
要修复验证错误,请创建一个 OpenAPI overlay 文件,并使用 speakeasy overlay apply -s <spec> -o <overlay> 应用它。
3. 生成 SDK
speakeasy quickstart --skip-interactive --output console \
-s openapi.json \
-t <target> \
-n <name> \
-p <package>
运行 speakeasy quickstart -s <spec> -t <language>,以初始化新的 SDK 项目。
示例
FastAPI 项目的完整工作流:
# 1. Extract the OpenAPI spec
cd /path/to/my-fastapi-project
python -c "import json; from main import app; print(json.dumps(app.openapi()))" > openapi.json
# 2. Validate
speakeasy lint openapi --non-interactive -s openapi.json
# 3. Generate a TypeScript SDK
speakeasy quickstart --skip-interactive --output console \
-s openapi.json \
-t typescript \
-n "MyApiSDK" \
-p "my-api-sdk"
添加 Speakeasy 扩展
提取规范后,添加 Speakeasy 专用扩展,以获得更好的 SDK 输出。可以在框架配置中添加这些扩展,也可以通过 overlay 添加。
FastAPI:通过 openapi_extra 添加扩展
@app.get(
"/items",
openapi_extra={
"x-speakeasy-retries": {
"strategy": "backoff",
"backoff": {"initialInterval": 500, "maxInterval": 60000, "exponent": 1.5},
"statusCodes": ["5XX", "429"]
},
"x-speakeasy-group": "items",
"x-speakeasy-name-override": "list"
}
)
def list_items(): ...
Django:通过 SPECTACULAR_SETTINGS 添加扩展
# settings.py
SPECTACULAR_SETTINGS = {
# ... other settings
'EXTENSIONS_TO_SCHEMA_FUNCTION': lambda generator, request, public: {
'x-speakeasy-retries': {
'strategy': 'backoff',
'backoff': {'initialInterval': 500, 'maxInterval': 60000, 'exponent': 1.5},
'statusCodes': ['5XX']
}
}
}
Spring Boot:通过自定义 OperationCustomizer 添加扩展
@Bean
public OperationCustomizer operationCustomizer() {
return (operation, handlerMethod) -> {
operation.addExtension("x-speakeasy-group",
handlerMethod.getBeanType().getSimpleName().replace("Controller", "").toLowerCase());
return operation;
};
}
NestJS:通过装饰器选项添加扩展
@Get()
@ApiOperation({
summary: 'List items',
operationId: 'listItems'
})
@ApiExtension('x-speakeasy-group', 'items')
@ApiExtension('x-speakeasy-name-override', 'list')
listItems() { ... }
通过 Overlay(适用于任何框架)
如果无法修改框架代码,请使用 overlay:
overlay: 1.0.0
info:
title: Speakeasy Extensions
version: 1.0.0
actions:
- target: $.paths['/items'].get
update:
x-speakeasy-group: items
x-speakeasy-name-override: list
提取后的常见问题
| 问题 | 症状 | 修复方法 |
|---|---|---|
| 缺少 operationIds | Lint 警告;SDK 方法名称泛化 | 通过 overlay 添加 operationIds,或使用 speakeasy suggest operation-ids -s openapi.json |
| 缺少描述 | Lint 提示;SDK 没有文档 | 在源代码或通过 overlay 为端点和架构添加描述 |
| 架构过于宽松 | 架构使用 additionalProperties: true,或缺少类型约束 | 在源代码中收紧架构;使用更严格的验证装饰器 |
| 没有响应架构 | Lint 错误;SDK 返回类型为 any/object | 为框架端点添加明确的响应模型 |
| operationIds 重复 | Lint 错误;生成失败 | 确保每个端点都有唯一的 operationId |
| 缺少身份验证 | 规范中没有安全方案 | 在框架配置中或通过 overlay 添加安全元数据 |
不要这样做
- 不要在框架能够生成 OpenAPI 规范时手动编写规范——务必先提取
- 不要直接编辑提取出的规范——使用 overlays 修复问题,以免重新提取时丢失更改
- 不要跳过验证——提取出的规范往往存在会阻碍 SDK 生成的问题
- 不要认为提取出的规范是完整的——框架可能会省略身份验证、错误响应或标头
- 不要在生产模式下启动服务器来提取规范——请使用开发或测试配置
故障排查
| 错误 | 原因 | 解决方案 |
|---|---|---|
ModuleNotFoundError(Python) | 未安装应用依赖 | 运行 pip install -r requirements.txt 或 pip install -e . |
| 连接被拒绝(Spring Boot、NestJS) | 服务尚未完全启动 | 延长等待时间或轮询检查是否就绪 |
| 规范为空或内容很少 | 导入时未注册路由 | 确保导入所有路由模块;检查延迟加载 |
| YAML 解析错误 | 提取的文件语法无效 | 重新提取;检查是否有 print 语句污染标准输出 |
Cannot find module(Node.js) | 未安装依赖 | 运行 npm install 或 yarn install |
没有 /v3/api-docs 端点(Spring Boot) | 未配置 springdoc | 将 springdoc-openapi-starter-webmvc-ui 添加到依赖项 |
没有 /api-json 端点(NestJS) | 未设置 Swagger 模块 | 在 main.ts 中配置 SwaggerModule.setup(app, ...) |
相关技能
manage-openapi-overlays- 通过 overlay 添加 x-speakeasy-* 扩展start-new-sdk-project- 提取后生成 SDK