Skip to content

[BUG][Python-Flask] Missing import when deserializing (composed) models #1665

@tomghyselinck

Description

@tomghyselinck
Description

We have a composed model: A House which has a Door.

When a client calls PUT /house, the server fails to deserialize the given input (in the request body).

[2018-12-12 08:58:52,961] ERROR in app: Exception on /house [PUT]
Traceback (most recent call last):
  File "/home/tom/.local/lib/python3.5/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  ...
  File "/home/tom/.local/lib/python3.5/site-packages/connexion/decorators/parameter.py", line 131, in wrapper
    return function(**kwargs)
  File "/home/tom/issues/python-flask-deserialize/openapi_server/controllers/default_controller.py", line 30, in house_put
    house = House.from_dict(connexion.request.get_json())  # noqa: E501
  File "/home/tom/issues/python-flask-deserialize/openapi_server/models/house.py", line 43, in from_dict
    return util.deserialize_model(dikt, cls)
  File "/home/tom/issues/python-flask-deserialize/openapi_server/util.py", line 101, in deserialize_model
    instance = klass()
  File "/home/tom/issues/python-flask-deserialize/openapi_server/models/house.py", line 25, in __init__
    'door': Door
NameError: name 'Door' is not defined

The problem exists because the House implementation (python-flask-deserialize/openapi_server/models/house.py) defines:

self.openapi_types = {
    'door': Door
}

without including the definition of Door.

openapi-generator version

I used OpenAPI generator CLI version 4.0.0-SNAPSHOT:
https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/4.0.0-SNAPSHOT/openapi-generator-cli-4.0.0-20181210.103357-85.jar

OpenAPI declaration file content or url

See python-flask-desrialize.yaml in the attached zip-file:
python-flask-deserialize.zip

Command line used for generation
java -jar openapi-generator-cli-4.x.jar generate -i ./python-flask-deserialize.yaml -g python-flask -o ./python-flask-deserialize/
Steps to reproduce
  1. Generate the server code

    ./python-flask-deserialize.sh
    
  2. Start the server

    (cd python-flask-deserialize && python3 -m openapi_server)
    
  3. Perform a client request

    curl -X PUT "http://localhost:8080/house" -H  "accept: */*" -H  "Content-Type: application/json" -d "{\"door\":{\"style\":\"old-fashion\"}}"
    

    Returns:

    {
      "detail": "The server encountered an internal error and was unable to complete your request.  Either the server is overloaded or there is an error in the application.",
      "status": 500,
      "title": "Internal Server Error",
      "type": "about:blank"
    }
    
Related issues/PRs
Suggest a fix

There are two possible fixes IMHO.
Either:

  • Import the child models of the composed model:
    from openapi_server.models.door import Door
    
  • Allow deserialization by the model "name" (string). See also implementation in the generated (python) client code (i.e. def __deserialize(self, data, klass) in api_client.py).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions