openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG] [Python] oneOf not using the discriminator

Open fybJenkins opened this issue 5 months ago • 1 comments

Bug Report Checklist

  • [x] Have you provided a full/minimal spec to reproduce the issue?
  • [x] Have you validated the input using an OpenAPI validator (example)?
  • [x] Have you tested with the latest master to confirm the issue still exists?
  • [x] Have you searched for related issues/PRs?
  • [x] What's the actual output vs expected output?
  • [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

We have an endpoint that returns a oneOf response, using a discriminator field.

It seems the generated code tries to parse the JSON as every object in the oneOf, and counts matches. The problem here is that, in our case, it manages to parse for both Product and ServerProduct, resulting in an error being thrown.

Instead, we expect that the discriminator field is used in order to parse the response as the correct type - using the propertyName and mappings as shown below.

In addition, the discriminator_value_class_map seems to be empty (despite us having discriminators) and unused.

If it helps, all of this is generated correctly (aka, using the discriminator) in both Go and Ruby.

openapi-generator version

7.2.0

OpenAPI declaration file content or url
responses:
  '200':
    description: List of all the products.
    content:
      application/json:
        schema:
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/Product'
              - $ref: '#/components/schemas/ServerProduct'
            discriminator:
              propertyName: productCategory
              mapping:
                SERVER: '#/components/schemas/ServerProduct'
                BANDWIDTH: '#/components/schemas/Product'
                OPERATING_SYSTEM: '#/components/schemas/Product'
                STORAGE: '#/components/schemas/Product'
                PUBLIC_IP: '#/components/schemas/Product'
Generation Details

Here we're generating a Python SDK, using this command:

openapi-generator-cli generate -i ${{ inputs.spec-link }} -c openapi-generator-config.yaml -o=${{ inputs.package-name }} --additional-properties packageName=${{ inputs.package-name }}

Here's the config:

generatorName: python
ignoreFileOverride: ".openapi-generator-ignore"
templateDir: "template"

In this case, we're not overriding the generation of oneOf models with our template, so we're using the default.

Steps to reproduce
  • Generate an SDK that has an endpoint which returns a oneOf model, where all options are similar (or identical for testing purposes).
  • Attempt to call that endpoint using the SDK (can use a mock server)
  • Get a similar error to this:
ValueError: Multiple matches found when deserializing the JSON string into ProductsGet200ResponseInner with oneOf schemas: Product, ServerProduct. Details: 
Related issues/PRs

Couldn't find any, unfortunately.

Suggest a fix

The fix in this case would be to update the template for the model_oneof.mustache so that it utilises the discriminator instead.

The discriminator_value_class_map can be used here, but it should be fixed so that the map is generated correctly. I don't know how to fix this or use the actual discriminator values.

fybJenkins avatar Feb 01 '24 15:02 fybJenkins

Have you tried the following config?

useOneOfDiscriminatorLookup: true

fa0311 avatar Feb 14 '24 04:02 fa0311