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

[BUG] [PYTHON] Model property: required AND default NOT combinable

Open Poolmann opened this issue 1 year ago • 2 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

I want to have a required property with a default value. When I require it in the model spec, it loses the default= parameter in the Field() constructor. I need it to be required since, if it isn't, it could be None.

Firstly, is this intended? If so how am I supposed to set up the property? If not, please help :)

openapi-generator version

master/7.5.0

OpenAPI declaration file content or url
openapi: 3.0.0
info:
  title: Title
  description: Title
  version: 1.0.0
paths:
  '/user':
    get:
      responses:
        200:
          description: "success"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequiredProperties'

components:
  schemas:
    RequiredProperties:
      type: object
      required:
        - requiredWithDefault
        - requiredWithoutDefault
      properties:
        requiredWithoutDefault:
          type: string
        requiredWithDefault:
          type: string
          default: "4.5.0"
        notRequiredWithDefault:
          type: string
          default: "4.5.0"
        notRequiredWithoutDefault:
          type: string
Generation Details

java -jar openapi-generator-cli.jar generate -i required.yaml -g python -o object --additional-properties packageName=object_client

Steps to reproduce
  1. Generate from provided spec
  2. See Model class
class RequiredProperties(BaseModel):
    """
    RequiredProperties
    """ # noqa: E501
    required_with_default: StrictStr = Field(alias="requiredWithDefault")
    required_without_default: StrictStr = Field(alias="requiredWithoutDefault")
    not_required_with_default: Optional[StrictStr] = Field(default='4.5.0', alias="notRequiredWithDefault")
    not_required_without_default: Optional[StrictStr] = Field(default=None, alias="notRequiredWithoutDefault")
    __properties: ClassVar[List[str]] = ["requiredWithDefault", "requiredWithoutDefault", "notRequiredWithDefault", "notRequiredWithoutDefault"]

Interestingly enough, the default shows up in the from_dict() classmethod:

        _obj = cls.model_validate({
            "requiredWithDefault": obj.get("requiredWithDefault") if obj.get("requiredWithDefault") is not None else '4.5.0',
            "requiredWithoutDefault": obj.get("requiredWithoutDefault"),
            "notRequiredWithDefault": obj.get("notRequiredWithDefault") if obj.get("notRequiredWithDefault") is not None else '4.5.0',
            "notRequiredWithoutDefault": obj.get("notRequiredWithoutDefault")
        })
Suggest a fix

I haven't quite found the problem yet, I'm pretty sure this is the part that's causing it: https://github.com/OpenAPITools/openapi-generator/blob/a4cf255dce69b74fabe49161d75bdc39851d1d95/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonPydanticV1Codegen.java#L914

Poolmann avatar Apr 30 '24 09:04 Poolmann

a required property cannot have a default value because it's "required" which means users must provide a value

wing328 avatar Apr 30 '24 13:04 wing328

But as one can see above, the property then becomes an typing.Optional. How should I signal to users to not pass None to it?

Poolmann avatar Apr 30 '24 14:04 Poolmann