Flask使用ApiSpec对接Swagger UI生成接口文档时触发TypeError报错
问题根因
报错由多个配置错误共同触发:
- YAML文档缩进不合法:写在方法docstring里的OpenAPI注释没有遵循YAML强缩进规则,
200:状态码下的description、content、headers字段全部和状态码同级,apispec解析时读不到200对应的响应配置,拿到None值,后续执行"headers" in response判断时就会触发「None类型不可迭代」的类型错误。 - OpenAPI 3.0响应头格式错误:用数组列表格式配置响应头不符合3.0版本规范,正确格式是键值对映射,以响应头名称作为key。
- 类方法参数缺失:
TestDataApi类下的get方法没有加self参数,接口发起请求时会触发参数不匹配错误。 - 路由重复注册:先后两次绑定了同路径接口,先给
api蓝图挂载了带前缀的test_data蓝图,后面又直接给app实例绑定了同路径路由,后续可能出现路径匹配冲突。
报错栈里提到additives_view是因为该视图对应的方法docstring也存在完全相同的缩进问题,不是只有TestDataApi接口有问题。
修复方案
- 修正所有接口方法docstring的缩进、响应头格式,补全类方法参数,以
get方法为例,正确写法如下:
from flask.views import MethodView from flask import Blueprint, after_this_request, make_response import json test_data = Blueprint('test', __name__, url_prefix='/testdata') class TestDataApi(MethodView): def get(self): """Get all TestData. --- description: Get a random data security: - ApiKeyAuth: [] responses: 200: description: Return all the TestData content: application/json: schema: TestDataSchema headers: X-Total-Items: $ref: '#/components/headers/X-Total-Items' X-Total-Pages: $ref: '#/components/headers/X-Total-Pages' """ data = TestData.query.all() response_data = test_schema.dump(data) resp = make_response(json.dumps(response_data), 200) return resp
- 调整app.py里的路由注册逻辑,去掉重复注册的代码,确保视图先注册到蓝图、再挂载到app,最后再给apispec传入视图生成路径规范:
api = Blueprint('api', __name__, url_prefix="/api/v0") spec = APISpec( title='Test Backend', version='v1', openapi_version='3.0.2', plugins=[MarshmallowPlugin(), FlaskPlugin()], ) # 先把视图绑定到对应蓝图 test_view = TestDataApi.as_view('test_api') test_data.add_url_rule('/', view_func=test_view, methods=['GET',]) # 再把蓝图注册到上层蓝图、最后挂载到app api.register_blueprint(test_data) app.register_blueprint(api) spec.components.schema("TestData", schema=TestDataSchema) # 路由注册完成后再生成spec路径 spec.path(view=test_view, operations=dict(get={})) SWAGGER_URL = '/api/v0/docs' API_URL = 'swagger.json' swaggerui_blueprint = get_swaggerui_blueprint( SWAGGER_URL, API_URL, config={ 'app_name': "Backend" } ) app.register_blueprint(swaggerui_blueprint)
其他和additives_view类似的接口,全部按相同规则检查docstring缩进即可。
改完重启服务,apispec就能正常解析所有接口注释,Swagger UI可以正常加载展示。
内容的提问来源于stack exchange,提问作者Harshita
相关产品推荐
相关产品推荐

