OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
21.54k stars 6.51k forks source link

[BUG] Python client: response parsing fails for array of anyOf items #6546

Closed hleb-albau closed 2 years ago

hleb-albau commented 4 years ago

Bug Report Checklist

Description

If openapi definition contains model of type array with anyOf items description, generated Python client can't parse request from server. Generated model has openapi_types with next type list[AnyOfFirstSecondThird]. During response parsing client takes one by one list items and try to de-serialize to non existing type klass AnyOfFirstSecondThird. Parsing fails at klass = getattr(openapi_client.models, klass) line with next error - module 'openapi_client.models' has no attribute 'AnyOfFirstSecondThird'

openapi-generator version

latest master, 5.0.0-SNAPSHOT

OpenAPI declaration file content or url
    ContainerList:
       type: array
       items:
         anyOf:
           - $ref: "#/components/schemas/FirstResultType"
           - $ref: "#/components/schemas/SecondResultType"
           - $ref: "#/components/schemas/ThirdResultType"
Command line used for generation
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate -i /local/docs/openapi.yml -g python -o /local/clients/python
Steps to reproduce
Related issues/PRs
Suggest a fix
auto-labeler[bot] commented 4 years ago

👍 Thanks for opening this issue! 🏷 I have applied any labels matching special text in your issue.

The team will review the labels and make any necessary changes.

spacether commented 4 years ago

@hleb-albau have you tried using the python-experimental generator? The python generator does not fully implement composed schemas but the python-experimentalgenerator does. You can see tests of the anyOf class gmFruit here That class is defined here and is defined as:

    gmFruit:
       properties:
          color:
             type: string
       anyOf:
          - $ref: '#/components/schemas/apple'
          - $ref: '#/components/schemas/banana'
       additionalProperties: false
hleb-albau commented 4 years ago

@spacether I tried to use python-experimental and got same results, but with slight different error - KeyError sys.modules[model.any_of_first_second_third']. And of course, model package does not contain any_of_first_second_third. Also, the problem not directly related to case tested by gmFruit , but rather combination of array and it's type definition.

Btw, I tried online swagger editor and generate another version on client. Seems it is generated by swagger-generator. Using that client I get lucky with response parsing. But in the middle of de-serialization anyOf types were lost and replaces by raw dict.

I should prepare some full example, need some time.

spacether commented 4 years ago

Ah, I was missing that this was an array model. I though that it was an object type model. Can you provide the referenced anyOf models?

We don't yet have code coverage of this use case in python-experimental.

spacether commented 4 years ago

In the short term, you could make an anyOf model which contains your anyOf definition. Then in your array model, just $ref to your new anyof model. That should work in python-experimental.

We also had a PR that just landed which creates arrayModels in python-experimental so

spacether commented 3 years ago

This issue's root cause is that inline composed schemas are not handled by generators at this time. Our tooling assumes that composed schemas are defined in components. A more general solution is to add composed schema CodegenProperties and have generators use that inline definition. These issues have the same root cause:

In this proof of concept PR I show how we can add composed schema info to: CodegenModel/CodegenProperty/CodegenParameter/CodegenResponse and then we can define these composed schemas at any level in generated code. https://github.com/OpenAPITools/openapi-generator/pull/8325 See this working in ComposedOneOfDifferentTypes here and see tests of it here

spacether commented 2 years ago

This work in python-experimental One can see anyOf endpoints here: https://github.com/OpenAPITools/openapi-generator/blob/master/samples/openapi3/client/3_0_3_unit_test/python-experimental/docs/apis/tags/AnyOfApi.md And anof model tests here: https://github.com/OpenAPITools/openapi-generator/blob/master/samples/openapi3/client/3_0_3_unit_test/python-experimental/test/test_models/test_anyof_complex_types.py Which are passing in CI in node 4

spacether commented 1 year ago

python-experimental became the default python client in v6.2.0 If you upgrade your python client to that version, this feature will work for you