具有多个规范的外部 YAML 不适用于 Flasgger

Posted

技术标签:

【中文标题】具有多个规范的外部 YAML 不适用于 Flasgger【英文标题】:External YAML with multiple specs not working on Flasgger 【发布时间】:2022-01-18 10:29:24 【问题描述】:

我试图通过引用同一个 YAML 文件来记录多个端点,但它不起作用。这不支持吗?还是我做错了什么?

app.py

from flask import Flask, jsonify
from flasgger import Swagger

app = Flask(__name__)
Swagger(app)

@app.route('/colors1/<palette>/')
def colors1(palette):
    """
    file: ../colors.yaml
    """
    all_colors = 
        'cmyk': ['cyan', 'magenta', 'yellow', 'black'],
        'rgb': ['red', 'green', 'blue']
    
    if palette == 'all':
        result = all_colors
    else:
        result = palette: all_colors.get(palette)

    return jsonify(result)

@app.route('/colors2/<palette>/')
def colors2(palette):
    """
    file: ../colors.yaml
    """
    all_colors = 
        'cmyk': ['cyan', 'magenta', 'yellow', 'black'],
        'rgb': ['red', 'green', 'blue']
    
    if palette == 'all':
        result = all_colors
    else:
        result = palette: all_colors.get(palette)

    return jsonify(result)

colors.yaml

Multiple endpoint specs
---
paths:
  /colors1/:
    get:
      parameters:
        - name: palette
          in: path
          type: string
          enum: ['all', 'rgb', 'cmyk']
          required: true
          default: all
      responses:
        200:
          description: A list of colors (may be filtered by palette)
          schema:
            $ref: '#/components/schema/Palette'
          examples:
            rgb: ['red', 'green', 'blue']
  /colors2/:
    get:
      parameters:
        - name: palette
          in: path
          type: string
          enum: ['all', 'rgb', 'cmyk']
          required: true
          default: all
      responses:
        200:
          description: A list of colors (may be filtered by palette)
          schema:
            $ref: '#/components/schema/Palette'
          examples:
            rgb: ['red', 'green', 'blue']
components:
  schemas:
    Palette:
      type: object
      properties:
        palette_name:
          type: array
          items:
            $ref: '#/components/schema/Color'
    Color:
      type: string

预期结果

具有完整规范(示例、响应、参数等)的两个端点,就像 README 中的屏幕截图中的规范一样。

实际结果

规格不完整,缺少很多细节:

【问题讨论】:

【参考方案1】:

为什么它不起作用?

Flasgger 似乎不支持在单个外部 YAML 文件中包含多个规范。因此,您需要将每个端点规范放在一个单独的文件中。

为什么 Swagger-UI 中缺少细节?

您的colors.yaml 文件中存在一些问题:

它包括超过Flasgger expects 它包含来自OpenAPI 2.0(又名 Swagger 2.0)和OpenAPI 3 规格的部分,Flasgger uses 2.0 by default

解决方案 1. 使用 OpenAPI 2.0

这是colors.yaml 的外观,以便 Flasgger 可以理解

Colors endpoint spec
---

parameters:
  - name: palette
    in: path
    type: string
    enum:
      - all
      - rgb
      - cmyk
    required: true
    default: all

responses:
  '200':
    description: A list of colors (may be filtered by palette)
    schema:
      $ref: '#/definitions/Palette'
    examples:
      rgb:
        - red
        - green
        - blue

definitions:
  Palette:
    type: object
    properties:
      palette_name:
        type: array
        items:
          $ref: '#/definitions/Color'
    example:
      rgb:
        - red
        - green
        - blue
  Color:
    type: string
    example: red

解决方案 2. 使用 OpenAPI 3(Flasgger 不完全支持)

根据 Flasgger repo,OpenAPI 3 支持是experimental

有对 OpenAPI 3.0 的实验性支持,在使用 SwaggerUI 3 时应该可以工作。

因此,可以在 OpenAPI 3 模式下使用带有外部规范文件的 Flasgger,但并非所有情况都受支持。例如,有一个关于将 components 引用与外部 YAML 文件一起使用的未解决问题(请参阅问题 #308)。

如果你仍然坚持,这是你应该做的。

步骤 1. 启用 OpenAPI 3

在您的app.py 文件中更新app.config

app = Flask(__name__)
app.config['SWAGGER'] = 
    'openapi': '3.0.0'

swagger = Swagger(app)

步骤 2. 更新规范以使用 OpenAPI 3

使用以下内容更新您的 colors.yaml 文件。

重要提示:请注意,由于上述the issue,我们必须内联模型架构定义而不是使用$ref 规范。

Colors endpoint spec
---

parameters:
  - name: palette
    in: path
    schema:
      type: string
      enum: ['all', 'rgb', 'cmyk']
      default: all
    required: true

responses:
  200:
    description: A list of colors (may be filtered by palette)
    content:
      application/json:
        schema:
          type: object
          properties:
            palette_name:
              type: array
              items:
                type: string
                example: red
          example:
            rgb:
              - red
              - green
              - blue
        example:
          rgb: ['red', 'green', 'blue']

【讨论】:

我在您提供的 YAML 示例中没有看到多个端点。例如,我只看到一个描述。如何让每个端点都有不同的描述? @Ariel,是的,对不起。更新了答案

以上是关于具有多个规范的外部 YAML 不适用于 Flasgger的主要内容,如果未能解决你的问题,请参考以下文章

分页列表不适用于具有多个模型的视图

YAML书写规范

Typeahead JS 不适用于具有相同类的多个输入

AWS - SAM cli yaml 模板不适用于 cloudformation 堆栈

在 YAML 文件中设置 DEFAULT_VIEW_INCLUSION 不适用于 MapperFeature.DEFAULT_VIEW_INCLUSION

Cordova 不适用于 iOS 多个目标