bigywater.tech
Flask · 114

OpenAPI 文档生成

怎么让接口文档不和代码脱节?OpenAPI 文档能不能自动生成?校验规则会不会进文档?这篇用 apispec 与 flask-smorest 真的生成一份文档,并用校验器检查它是否合法。

3.0.3
生成的 OpenAPI 版本,通过 openapi-spec-validator 校验
422
smorest 校验失败的状态码,并自动写进文档
readOnly
marshmallow 的 dump_only 在文档里的样子

apispec 生成文档

实测 · 本机执行输出
  顶层键: ['paths', 'info', 'openapi', 'components']
  paths: ['/users/{uid}']
  components.schemas: ['User']
  User 模型生成的 schema: {"type": "object", "properties": {"id": {"type": "integer", "readOnly": true}, "name": {"type": "string", "minLength": 1, "maxLength": 20}, "age": {"type": "integer", "minimum": 0, "maximum": 150}}, "required": ["name"], "additionalProperties": false}
  视图 docstring 里引用 "UserSchema" 被解析成: {'$ref': '#/components/schemas/User'}
  Flask 的 <int:uid> 路由被转成 OpenAPI 的路径: /users/{uid}
  openapi-spec-validator:文档合法

上一篇:ETag API 缓存;下一篇:Marshmallow 序列化。

校验规则进文档

实测 · 本机执行输出
  name: {'type': 'string', 'minLength': 1, 'maxLength': 20} | age: {'type': 'integer', 'minimum': 0, 'maximum': 150} | id: {'type': 'integer', 'readOnly': True}
  required: ['name']

flask-smorest

实测 · 本机执行输出
  GET /openapi.json → 200 | openapi = 3.0.3 | paths = ['/users/']
  /users/ 下的方法: ['get', 'post'] | POST 的响应码: ['422', '201', 'default']
  文档合法
  GET /docs(Swagger UI)→ 200 text/html | 页面里引用的脚本源: True
  (Swagger UI 的 JS 来自 CDN——离线环境或有内容安全策略的站点要自己托管,本篇没有在浏览器里渲染它)

自动校验

实测 · 本机执行输出
  POST {name:"", age:200} → 422 {"code": 422, "errors": {"json": {"age": ["Must be greater than or equal to 0 and less than or equal to 150."], "name": ["Length must be between 1 and 20."]}}, "status": "Unprocessable Entity"}
  多余字段 extra → 422 {'json': {'extra': ['Unknown field.']}}
  合法 → 201 {'age': 5, 'id': 2, 'name': 'bob'}
  文档里写了 422 响应吗: True

文档跟着代码变

实测 · 本机执行输出
  required 变成: ['age', 'name'] (之前是 ['name'])
  手写的 YAML docstring 不会自动跟着变——这部分仍要靠人维护

分步演示

OpenAPI 文档生成
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动。apispec 6.10.0、apispec-webframeworks 1.2.0、marshmallow 4.3.1、flask-smorest 0.47.0、openapi-spec-validator 0.9.0
    • 没有验证:Swagger UI 在浏览器里的渲染、OpenAPI 3.1、认证方案(securitySchemes)的描述、按版本拆分多份文档、用生成的文档做契约测试或客户端代码生成
    京ICP备2026067502号-1京公网安备11010502063487号