首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在flasgger中将棉花糖定义和多版本规范结合在一起?

如何在flasgger中将棉花糖定义和多版本规范结合在一起?
EN

Stack Overflow用户
提问于 2021-06-02 06:30:00
回答 1查看 514关注 0票数 2

我将使用Flasgger和APISpec从棉花糖模式加载初始定义。同时,我希望有多个版本的API文档。这是我的代码:

代码语言:javascript
复制
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文档:

代码语言:javascript
复制
@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)一起加载!我的代码有什么问题吗?或者我的解决方案完全错了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-07 01:01:48

最后,我找到了一个解决方案(也许不是最好的,但效果很好)。

这很简单,只需从template输入中删除Swagger(...)参数,而不是将definitions添加到configs dict。让我们看看最终结果:

代码语言:javascript
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67799995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档