Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • O openapi-generator
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,476
    • Issues 3,476
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 402
    • Merge requests 402
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • OpenAPI Tools
  • openapi-generator
  • Merge requests
  • !10809

[PYTHON] Setting default value for Required variables

  • Review changes

  • Download
  • Email patches
  • Plain diff
Merged Administrator requested to merge github/fork/the-akhil-nair/req_vars_changes into master Nov 08, 2021
  • Overview 0
  • Commits 11
  • Pipelines 0
  • Changes 56

Created by: the-akhil-nair

Problem: In the following PR: https://github.com/OpenAPITools/openapi-generator/pull/8802

The requiredVars have been moved out of the composed schema __init__ and _from_openapi_data signature because the required vars were probably defined in the composed oneOf/anyOf/allOf schemas and this schema does not know about them. We understand that each schema should be validated separately and required vars of a schema should not be present in composed schema, but while doing the validation of input payload in allOf schema the schema is expecting those requiredVars to be set and sent in the input payload itself.

For Example, consider the following snippet from the specification file:

schemas:
    Dog:
      allOf:
        - $ref: '#/components/schemas/Mammals'
        - type: object
          properties:
            className:
              enum:
                - 'Dog'
              x-enum-as-string: true
              default: 'Dog'
              type: string
            breed:
              type: string
            legs:
               $ref: '#/components/schemas/Legs'
    Cat:
      allOf:
        - $ref: '#/components/schemas/Mammals'
        - type: object
          properties:
            className:
              enum:
                - 'Cat'
              x-enum-as-string: true
              default: 'Cat'
              type: string
            declawed:
              type: boolean
            legs:
               $ref: '#/components/schemas/Legs'
    Legs:
        type: object
        required:
        - legs
        properties:
            legs:
              enum:
              - '2'
              - '4'
              default: '4'
              x-enum-as-string: true
            name:
               type: string
    Mammals:
      allOf:
        - $ref: '#/components/schemas/Animal'
        - type: object
          required:
            - className
          properties:
            className:
              enum:
                - 'Dog'
                - 'Cat'
              x-enum-as-string: true
              type: string
    Animal:
      type: object
      required:
        - className
      properties:
        className:
          enum:
            - 'Dog'
            - 'Cat'
          x-enum-as-string: true
          type: string
        color:
          type: string
          default: red
        run:
           type: boolean
           default: True
           readOnly: true

As we can see in the above case Dog class contain the Mammals class as part of allOf composed schema. Now if we will not specify the className in Dog class as payload and when the payload will be validated against Mammals class and Animal class, Mammal class will throw an error.

Code used to test:

from openapi_client.model.dog import Dog
from openapi_client.model.legs import Legs


def define_legs():
    return Legs(legs="4")


def dog():
    legs = define_legs()

    dog_instance = Dog(color="Black")

    dog_instance.breed = "Bulldog"

    dog_instance.legs = legs

dog()

Error Captured:

Traceback (most recent call last):
  File "E:\Dev\Required_Vars\animal\openapi_client\model_utils.py", line 1782, in get_allof_instances
    allof_instance = allof_class(**model_args, **constant_args)
  File "E:\Dev\Required_Vars\animal\openapi_client\model_utils.py", line 45, in wrapped_init
    return fn(_self, *args, **kwargs)
TypeError: __init__() missing 1 required positional argument: 'class_name'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "E:\Dev\Required_Vars\animal\openapi_client\model_utils.py", line 1782, in get_allof_instances
    allof_instance = allof_class(**model_args, **constant_args)
  File "E:\Dev\Required_Vars\animal\openapi_client\model_utils.py", line 45, in wrapped_init
    return fn(_self, *args, **kwargs)
  File "E:\Dev\Required_Vars\animal\openapi_client\model\mammals.py", line 289, in __init__
    composed_info = validate_get_composed_info(
  File "E:\Dev\Required_Vars\animal\openapi_client\model_utils.py", line 1988, in validate_get_composed_info
    allof_instances = get_allof_instances(self, model_args, constant_args)
  File "E:\Dev\Required_Vars\animal\openapi_client\model_utils.py", line 1785, in get_allof_instances
    raise ApiValueError(
openapi_client.exceptions.ApiValueError: Invalid inputs given to generate an instance of 'Animal'. The input data was invalid for the allOf schema 'Animal' in the co
mposed schema 'Mammals'. Error=__init__() missing 1 required positional argument: 'class_name'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "E:\Dev\Required_Vars\animal\examples.py", line 18, in <module>
    dog()
  File "E:\Dev\Required_Vars\animal\examples.py", line 12, in dog
    dog_instance = Dog(color="Black")
  File "E:\Dev\Required_Vars\animal\openapi_client\model_utils.py", line 45, in wrapped_init
    return fn(_self, *args, **kwargs)
  File "E:\Dev\Required_Vars\animal\openapi_client\model\dog.py", line 300, in __init__
    composed_info = validate_get_composed_info(
  File "E:\Dev\Required_Vars\animal\openapi_client\model_utils.py", line 1988, in validate_get_composed_info
    allof_instances = get_allof_instances(self, model_args, constant_args)
  File "E:\Dev\Required_Vars\animal\openapi_client\model_utils.py", line 1785, in get_allof_instances
    raise ApiValueError(
openapi_client.exceptions.ApiValueError: Invalid inputs given to generate an instance of 'Mammals'. The input data was invalid for the allOf schema 'Mammals' in the
composed schema 'Dog'. Error=Invalid inputs given to generate an instance of 'Animal'. The input data was invalid for the allOf schema 'Animal' in the composed schem
a 'Mammals'. Error=__init__() missing 1 required positional argument: 'class_name'

And because of this now it will become the user's responsibility to add the requiredVars as a mandatory input in the payload. That is user need to always specify the className in their payload like the following:

 dog_instance = Dog(class_name="Dog",
                       color="Black")

Since in our application end users may not be know these requiredVars always, the SDK failure creates an issue for us.

Solution: The proposed solution is to add a configuration variable: setRequiredVars. If it is set to true, then the older logic will be used. The older logic was used to set the default value of requiredVars in __init__ and _from_openapi_data as positional arguments.

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed responses from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package 
    ./bin/generate-samples.sh
    ./bin/utils/export_docs_generators.sh
    Commit all changed files. This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master. These must match the expectations made by your contribution. You may regenerate an individual generator bypassing the relevant config(s) as an argument to the script, for example, ./bin/generate-samples.sh bin/configs/java*. For Windows users, please run the script in Git BASH.
  • File the PR against the correct branch: master (5.3.0), 6.0.x
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request. @taxpon (2017/07) @frol (2017/07) @mbohlool (2017/07) @cbornet (2017/09) @kenjones-cisco (2017/11) @tomplus (2018/10) @Jyhess (2019/01) @arun-nalla (2019/11) @spacether (2019/11) @wing328
Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: github/fork/the-akhil-nair/req_vars_changes