swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
16.99k stars 6.03k forks source link

[python-flask] Generated code fails due to .from_dict syntax error. #10521

Open jethrogillgren opened 3 years ago

jethrogillgren commented 3 years ago
Description

The python-flask generated server doesn't run due syntax errors:

  File "/usr/src/app/swagger_server/controllers/default_controller.py", line 20
    filter = .from_dict(connexion.request.get_json())  # noqa: E501
Swagger-codegen version

3.0.22

Swagger declaration file content or url

Tested against the PetStore V 3.0 with an anyOf element, eg https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml with

          schema:
            oneOf:
            - type: string
            - type: integer

Or the below complete example:

openapi: "3.0.0"
info:
  title: "My API"
  version: "0.0.1"
paths:
  /invoices:
    get:
      parameters:
        - name: filter
          in: query
          description: Filter parameters
          required: false
          schema:
            type: object
            properties:
              field:
                type: string
      responses:
        '200':
          description: An array of invoices
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    number:
                      type: integer
                      format: int64
Command line used for generation
docker run --rm -v ${PWD}:/local swaggerapi/swagger-codegen-cli-v3:3.0.22  generate -i /local/swagger.yaml -l python-flask -o /local

19:14:45.328 [Thread-1] WARN  i.s.c.v.g.DefaultCodegenConfig - Empty operationId found for path: GET /invoices. Renamed to auto-generated operationId: invoicesGET
19:14:45.757 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/models/filter.py
19:14:45.811 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/models/inline_response200.py
19:14:45.930 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/controllers/default_controller.py
19:14:45.937 [Thread-1] INFO  i.s.codegen.v3.DefaultGenerator - File exists. Skipped overwriting /local/swagger_server/test/test_default_controller.py
19:14:46.099 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/README.md
19:14:46.107 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/setup.py
19:14:46.114 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/tox.ini
19:14:46.120 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/test-requirements.txt
19:14:46.129 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/requirements.txt
19:14:46.141 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/git_push.sh
19:14:46.153 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/.gitignore
19:14:46.163 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/.travis.yml
19:14:46.172 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/Dockerfile
19:14:46.184 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/.dockerignore
19:14:46.194 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/__init__.py
19:14:46.203 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/__main__.py
19:14:46.214 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/encoder.py
19:14:46.233 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/util.py
19:14:46.242 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/controllers/__init__.py
19:14:46.250 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/models/__init__.py
19:14:46.264 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/models/base_model_.py
19:14:46.275 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/test/__init__.py
19:14:46.286 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/swagger/swagger.yaml
connexion == 2.6.0
19:14:46.297 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/swagger_server/controllers/authorization_controller.py
19:14:46.302 [Thread-1] INFO  i.s.codegen.v3.AbstractGenerator - writing file /local/.swagger-codegen/VERSION
Steps to reproduce

generate using above command. Edit the requirements.txt to workaround existing bug https://github.com/swagger-api/swagger-codegen-generators/issues/780 docker build -t testcase . docker run testcase

Thanks for any assistance, we'd love to use the project.

srl295 commented 3 years ago

~Smaller~ different example:

openapi: '3.0.0'
tags:
  - name: baz
    description: Working Junk
  - name: bar
    description: Broken Junk
info:
  title: Test
  description: Test
  version: 0.0.1
paths:
  /foo/bar/{id}:
    delete:
      operationId: deleteBar
      summary: Delete bar
      tags:
      - bar
      parameters:
        - in: path
          name: id # does not work
          schema:
            $ref: '#/components/schemas/id'
          required: true
          description: id of junk to delete
      responses:
        200:
          description: "Deleted"
        404:
          description: "Not found"
  /foo/baz/{id}:
    delete:
      operationId: deleteBaz
      summary: Delete baz
      tags:
      - baz
      parameters:
        - in: path
          name: id
          schema: # "works"
            type: string
          required: true
          description: id of junk to delete
      responses:
        200:
          description: "Deleted"
        404:
          description: "Not found"
components:
  schemas:
    id:
      type: string
      description: id of junk
      example: 12345

**bar_controller.py

import connexion
import six

from swagger_server.models.id import Id  # noqa: E501
from swagger_server import util

def delete_bar(id):  # noqa: E501
    """Delete bar

     # noqa: E501

    :param id: id of junk to delete
    :type id: dict | bytes

    :rtype: None
    """
    if connexion.request.is_json:
        id = .from_dict(connexion.request.get_json())  # noqa: E501
    return 'do some magic!'

baz_controller.py

import connexion
import six

from swagger_server import util

def delete_baz(id):  # noqa: E501
    """Delete baz

     # noqa: E501

    :param id: id of junk to delete
    :type id: str

    :rtype: None
    """
    return 'do some magic!'

the bar_controller has the problem.

srl295 commented 3 years ago

DELETE can't have a requestBody so the junk line doesn't make sense.

srl295 commented 3 years ago

https://github.com/swagger-api/swagger-codegen/blob/068b1ebcb7b04a48ad38f1cadd24bb3810c9f1ab/modules/swagger-codegen/src/main/resources/flaskConnexion/controller.mustache#L68-L75

just a wild guess, but in my code there was a schema, but it was still a 'primitive type' of a string.

that, or the baseType didn't get set somehow

srl295 commented 3 years ago

actually, why isn't baseType set to Id in my example above?

srl295 commented 3 years ago

^ I'm on swagger-codegen 3.0.24

srl295 commented 3 years ago

I couldn't get my file to even load on the HEAD version (#10157).

Workaround: I found that openapi-generator@5.0.1 works fine, so I've switched to that.