python - 如何在 flasgger 中同时拥有棉花糖定义和多版本规范?
问题描述
我将使用 Flasgger 和 APISpec 从棉花糖模式中加载初始定义。除此之外,我还想拥有多个版本的 API 文档。这是我的代码:
from app.api.v1.controllers.assessment_controller import AssessmentCoachingRequestSchema, AssessmentCoachingResponseSchema
from app.api.v1.responses import AssessmentResultResponseSchema, ModuleScoreResponseSchema, RecommendedModulesListResponseSchema, UserModuleScoresListResponseSchema
from app.api.v1.requests import AssessmentCreateRequestSchema, AssessmentShowRequestSchema
from app.api.v1.routes import assesment
from flasgger import Swagger
from flask.app import Flask
from flasgger import APISpec, Schema, Swagger, fields
from apispec.ext.marshmallow import MarshmallowPlugin
from apispec_webframeworks.flask import FlaskPlugin
def configure_swagger(app: Flask):
# Create an APISpec
spec = APISpec(
title='API',
version='1.0.0',
openapi_version='2.0',
plugins=[
FlaskPlugin(),
MarshmallowPlugin(),
],
)
template = spec.to_flasgger(
app,
definitions=[AssessmentCreateRequestSchema, AssessmentResultResponseSchema,
AssessmentShowRequestSchema, AssessmentCoachingRequestSchema,
AssessmentCoachingResponseSchema, UserModuleScoresListResponseSchema,
RecommendedModulesListResponseSchema]
)
configs = {
"headers": [
],
"specs": [
{
"endpoint": 'v0_spec',
"route": '/v0',
"version": "0.0.0",
"title": "API v0",
"description": 'Version 0 of the API',
"rule_filter": lambda rule: rule.endpoint.startswith('api_v0'),
"model_filter": lambda tag: True, # all in
},
{
"endpoint": 'v1_spec',
"route": '/v1',
"version": "1.0.0",
"title": "API v1",
"description": 'Version 1 of the API',
"rule_filter": lambda rule: rule.endpoint.startswith('api_v1'),
"model_filter": lambda tag: True, # all in
},
{
"endpoint": 'test_v1_spec',
"route": '/tv1',
"version": "1.0.0",
"title": "API test v1",
"description": 'Test version 1 of the API',
"rule_filter": lambda rule: rule.endpoint.startswith('api_test_v1'),
"model_filter": lambda tag: True, # all in
},
{
"endpoint": 'experiment_v1_spec',
"route": '/exp',
"version": "1.0.0",
"title": "API experiment",
"description": 'Experiment API',
"rule_filter": lambda rule: rule.endpoint.startswith('api_exp'),
"model_filter": lambda tag: True, # all in
}
],
"static_url_path": "/flasgger_static",
# "static_folder": "static", # must be set by user
"swagger_ui": True,
"specs_route": "/apidocs/",
"title": "API",
"schemes": [
"http",
"https"
],
"securityDefinitions": {
"basicAuth": {
"type": "http",
"scheme": "basic"
}
},
"security":{"basicAuth": []}
}
swag = Swagger(app, config=configs, template=template)
我还尝试在蓝图的每条路线中使用此装饰器以 .yaml 格式加载 API 文档:
@api_v1_blueprint.route('/text-analysis', methods=['GET'])
@swag_from('/app/api/_docs/v1/text_analysis.yaml', methods=["GET"])
@auth.login_required
@validate_request(marshmallow_schema=TextAnalysisRequestSchema)
def text_analysis(request: TextAnalysisRequest):
return show_response(data=analyze_text(request), response_version=RESPONSE_VERSION)
但是当我使用 APISpec 模板时,规范路由不再起作用了!它不会过滤文档,只是将所有文档(v0 和 v1)一起加载!我的代码有问题还是我的解决方案完全错误?
解决方案
最后,我找到了一个解决方案(也许不是最好的,但效果很好)。
这很容易,只需template
从输入中删除参数Swagger(...)
,而不是添加definitions
到configs
dict. 让我们看看最终结果:
from app.api.v1.controllers.assessment_controller import AssessmentCoachingRequestSchema, AssessmentCoachingResponseSchema
from app.api.v1.responses import AssessmentResultResponseSchema, ModuleScoreResponseSchema, RecommendedModulesListResponseSchema, UserModuleScoresListResponseSchema
from app.api.v1.requests import AssessmentCreateRequestSchema, AssessmentShowRequestSchema
from app.api.v1.routes import assesment
from flasgger import Swagger
from flask.app import Flask
from flasgger import APISpec, Schema, Swagger, fields
from apispec.ext.marshmallow import MarshmallowPlugin
from apispec_webframeworks.flask import FlaskPlugin
def configure_swagger(app: Flask):
# Create an APISpec
spec = APISpec(
title='API',
version='1.0.0',
openapi_version='2.0',
plugins=[
FlaskPlugin(),
MarshmallowPlugin(),
],
)
template = spec.to_flasgger(
app,
definitions=[AssessmentCreateRequestSchema, AssessmentResultResponseSchema,
AssessmentShowRequestSchema, AssessmentCoachingRequestSchema,
AssessmentCoachingResponseSchema, UserModuleScoresListResponseSchema,
RecommendedModulesListResponseSchema]
)
configs = {
"headers": [
],
"definitions":template['definitions'],
"specs": [
{
"endpoint": 'v0_spec',
"route": '/v0',
"version": "0.0.0",
"title": "API v0",
"description": 'Version 0 of the API',
"rule_filter": lambda rule: rule.endpoint.startswith('api_v0'),
"model_filter": lambda tag: True, # all in
},
{
"endpoint": 'v1_spec',
"route": '/v1',
"version": "1.0.0",
"title": "API v1",
"description": 'Version 1 of the API',
"rule_filter": lambda rule: rule.endpoint.startswith('api_v1'),
"model_filter": lambda tag: True, # all in
},
{
"endpoint": 'test_v1_spec',
"route": '/tv1',
"version": "1.0.0",
"title": "API test v1",
"description": 'Test version 1 of the API',
"rule_filter": lambda rule: rule.endpoint.startswith('api_test_v1'),
"model_filter": lambda tag: True, # all in
},
{
"endpoint": 'experiment_v1_spec',
"route": '/exp',
"version": "1.0.0",
"title": "API experiment",
"description": 'Experiment API',
"rule_filter": lambda rule: rule.endpoint.startswith('api_exp'),
"model_filter": lambda tag: True, # all in
}
],
"static_url_path": "/flasgger_static",
# "static_folder": "static", # must be set by user
"swagger_ui": True,
"specs_route": "/apidocs/",
"title": "API",
"schemes": [
"http",
"https"
],
"securityDefinitions": {
"basicAuth": {
"type": "http",
"scheme": "basic"
}
},
"security":{"basicAuth": []}
}
swag = Swagger(app, config=configs)
推荐阅读
- sql - 需要从其他表的结果更新一个表
- python - 如何读取压缩文件夹中的 .pkl 文件
- reactjs - 我如何在来自 firebase 的 react js 中迭代这些数据并捕获用户生成的关键数据
- swift - RealityKit – 无法正确旋转对象
- excel - 如何跨多个工作簿/工作站维护 Power Query 代码?
- javascript - 如何根据注入的组件对组件中的 *ngFor 进行切片?
- mongodb - 如何根据选择框过滤器查找Mongodb文档并显示结果
- mongodb - MongoDB 社区 Kubernetes 操作员连接
- c++ - 使用 neon/simd 优化 Vector3 类
- javascript - 通过单击其中一个来猜测获胜按钮 - Vanilla JS