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

[BUG] python-experimental client fails to properly deserialize using discriminator

Open fbl100 opened this issue 3 years ago • 0 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

The python-experimental client does not properly deserialize an object when the only difference between two models is the discriminator.

Note that this could be solved by making the type_id an enum, but our use case does not allow for this. When using a discriminator, this should be enough for the client to resolve the type.

openapi-generator version

verified in v6.1.0 and :latest (as of 9/21/22)

OpenAPI declaration file content or url

The following spec can be used to generated a client:

openapi: 3.0.0
x-stoplight:
  id: mjnw03vw4ju5m
info:
  title: discriminator-test
  version: '1.0'
servers:
  - url: 'http://localhost:3000'
paths:
  /operators:
    post:
      summary: ''
      operationId: post-operators
      responses:
        '200':
          description: OK
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Operator'
components:
  schemas:
    AdditionOperator:
      type: object
      title: AdditionOperator
      x-stoplight:
        id: qtffupdjxr76d
      description: ''
      additionalProperties: false
      properties:
        a:
          type: number
          format: double
        b:
          type: number
          format: double
        operator_id:
          type: string
          default: ADD
      required:
        - a
        - b
        - operator_id
    Operator:
      title: Operator
      x-stoplight:
        id: gz5qgm5j0vayg
      oneOf:
        - $ref: '#/components/schemas/AdditionOperator'
        - $ref: '#/components/schemas/SubtractionOperator'
      discriminator:
        propertyName: operator_id
        mapping:
          ADD: '#/components/schemas/AdditionOperator'
          SUB: '#/components/schemas/SubtractionOperator'
      description: ''
    SubtractionOperator:
      type: object
      title: SubtractionOperator
      x-stoplight:
        id: qtffupdjxr76d
      description: ''
      additionalProperties: false
      properties:
        a:
          type: number
          format: double
        b:
          type: number
          format: double
        operator_id:
          type: string
          default: SUB
      required:
        - a
        - b
        - operator_id

-->

Generation Details

I generated my client using the dockerized version of the cli. The following was executed in powershell (with the spec being in the 'reference' directory)

docker run --rm -v "${PWD}/:/output" -v "${PWD}/reference:/input" openapitools/openapi-generator-cli:latest generate `
   -g python-experimental `
   -i /input/discriminator-test.yaml `
   -o /output/disc-test `
   --additional-properties=packageName=disc_test_api `
   --additional-properties=packageVersion=0.0.1
Steps to reproduce

After installing the client into a virtual environment, the following python will reproduce the error:

from disc_test_api.model.operator import Operator

x = {
    'a': 1.0,
    'b': 2.0,
    'operator_id': 'ADD'
}

op = Operator(**x)
print(op)

The error and stack trace is:

C:\code\openapi-ticket\venv\Scripts\python.exe C:/code/openapi-ticket/main.py 
Traceback (most recent call last):
  File "C:\code\openapi-ticket\main.py", line 10, in <module>
    op = Operator(**x)
  File "C:\code\openapi-ticket\disc-test\disc_test_api\model\operator.py", line 72, in __new__
    return super().__new__(
  File "C:\code\openapi-ticket\disc-test\disc_test_api\schemas.py", line 513, in __new__
    __path_to_schemas = cls.__get_new_cls(__arg, __validation_metadata)
  File "C:\code\openapi-ticket\disc-test\disc_test_api\schemas.py", line 381, in __get_new_cls
    other_path_to_schemas = cls._validate_oapg(arg, validation_metadata=validation_metadata)
  File "C:\code\openapi-ticket\disc-test\disc_test_api\schemas.py", line 1993, in _validate_oapg
    other_path_to_schemas = cls.__get_oneof_class(
  File "C:\code\openapi-ticket\disc-test\disc_test_api\schemas.py", line 1902, in __get_oneof_class
    raise ApiValueError(
disc_test_api.exceptions.ApiValueError: Invalid inputs given to generate an instance of <class 'disc_test_api.model.operator.Operator'>. Multiple oneOf schemas [<class 'disc_test_api.model.addition_operator.AdditionOperator'>, <class 'disc_test_api.model.subtraction_operator.SubtractionOperator'>] matched the inputs, but a max of one is allowed.
Related issues/PRs
Suggest a fix

fbl100 avatar Sep 21 '22 15:09 fbl100