1

I'm trying to document multiple endpoints by reference to the same YAML file but it just won't work. Is this not supported? Or am I doing something wrong?

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

Expected result

Two endpoints with full specs (examples, response, parameters, etc), just like the specs in the screenshot in the README.

Actual result

Incomplete specs with a lot of details missing:

image

Ariel
  • 3,383
  • 4
  • 43
  • 58

1 Answers1

1

Why it doesn't work?

Flasgger doesn't seem to support having multiple specs in a single external YAML file. So you will need to put each endpoint spec in a separate file.

Why are details missing in Swagger-UI?

There are few problems in your colors.yaml file:

Solution 1. Use OpenAPI 2.0

Here is how colors.yaml should look so Flasgger can understand it

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

Solution 2. Use OpenAPI 3 (not fully supported by Flasgger)

According to Flasgger repo, OpenAPI 3 support is experimental

There is experimental support for OpenAPI 3.0 that should work when using SwaggerUI 3.

So using Flasgger in OpenAPI 3 mode with external spec files is possible, but not all cases are supported. For example, there is an open issue about using components reference with external YAML file (see issue #308).

If you are still up to it, here is what you should do.

Step 1. Enable OpenAPI 3

Update app.config in your app.py file:

app = Flask(__name__)
app.config['SWAGGER'] = {
    'openapi': '3.0.0'
}
swagger = Swagger(app)

Step 2. Update specs to use OpenAPI 3

Update your colors.yaml file with the following content.

Important: Please note that we had to inline model schema definitions instead of using $ref spec due to the issue mentioned above.

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']
Sasha
  • 827
  • 1
  • 9
  • 16
  • 1
    I don't see multiple endpoints in the YAML examples you provided. I only see one description, for example. How do I get each endpoint to have a different description? – Ariel Dec 20 '21 at 14:40
  • @Ariel, Yes, sorry. Updated the answer – Sasha Dec 20 '21 at 15:00