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
20.51k stars 6.27k forks source link

[BUG] [Python] [7.6.0] pydantic reports 'Field may not be used twice on the same field' for generated models #18960

Open jili-zuora opened 1 week ago

jili-zuora commented 1 week ago

Bug Report Checklist

Description

if the model schema have more then 1 constraints like: description and maxLength, the generator generated python model can't work with pydantic.

1, generate the python client using command: openapi-generator-cli generate -i petstore.yaml -g python -o ./pet 2, run geneated pet.py, like: python3 pet.py

Traceback (most recent call last):
  File "/${home}/workspace/zuora-api/sdk-v1-samples/py-sdk-sample/sample/pet.py", line 26, in <module>
    class Pet(BaseModel):
  File "/${home}/.pyenv/versions/3.9.17/lib/python3.9/site-packages/pydantic/_internal/_model_construction.py", line 171, in __new__
    set_model_fields(cls, bases, config_wrapper, types_namespace)
  File "/${home}/.pyenv/versions/3.9.17/lib/python3.9/site-packages/pydantic/_internal/_model_construction.py", line 361, in set_model_fields
    fields, class_vars = collect_model_fields(cls, bases, config_wrapper, types_namespace, typevars_map=typevars_map)
  File "/${home}/.pyenv/versions/3.9.17/lib/python3.9/site-packages/pydantic/_internal/_fields.py", line 162, in collect_model_fields
    field_info = FieldInfo.from_annotated_attribute(ann_type, default)
  File "/${home}/.pyenv/versions/3.9.17/lib/python3.9/site-packages/pydantic/fields.py", line 310, in from_annotated_attribute
    default.annotation, annotation_metadata = cls._extract_metadata(annotation, default)
  File "/${home}/.pyenv/versions/3.9.17/lib/python3.9/site-packages/pydantic/fields.py", line 398, in _extract_metadata
    raise TypeError('Field may not be used twice on the same field')
TypeError: Field may not be used twice on the same field

pydantic == 2.0, python version: 3.9

openapi-generator version

7.6.0

OpenAPI declaration file content or url

the main reason is property lastName in Pet, which have two contraints: description and maxLength.

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://petstore.swagger.io/v1
paths:
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      tags:
        - pets
      parameters:
        - name: limit
          in: query
          description: How many items to return at one time (max 100)
          required: false
          schema:
            type: integer
            maximum: 100
            format: int32
      responses:
        '200':
          description: A paged array of pets
          headers:
            x-next:
              description: A link to the next page of responses
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    post:
      summary: Create a pet
      operationId: createPets
      tags:
        - pets
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
        required: true
      responses:
        '201':
          description: Null response
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /pets/{petId}:
    get:
      summary: Info for a specific pet
      operationId: showPetById
      tags:
        - pets
      parameters:
        - name: petId
          in: path
          required: true
          description: The id of the pet to retrieve
          schema:
            type: string
      responses:
        '200':
          description: Expected response to a valid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pet"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
components:
  schemas:
    Pet:
      type: object
      required:
        - id
        - name
        - lastName
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        tag:
          type: string
        lastName:
          description: 'this is desc'
          maxLength: 100
          type: string
    Pets:
      type: array
      maxItems: 100
      items:
        $ref: "#/components/schemas/Pet"
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string
Generation Details

openapi-generator-cli generate -i petstore.yaml -g python -o ./pet

Steps to reproduce

1, generate the python client using command: openapi-generator-cli generate -i petstore.yaml -g python -o ./pet 2, run geneated pet.py, like: python3 pet.py

Related issue should be last_name in pet.py:

    last_name: Annotated[str, Field(strict=True, max_length=100)] = Field(description="this is desc", alias="lastName")

My understanding, correct one should be:

    last_name: Annotated[str, Field(strict=True, max_length=100, description="this is desc", alias="lastName")]
Related issues/PRs
Suggest a fix
wing328 commented 1 week ago

thanks for reporting the issue

cc @cbornet (2017/09) @tomplus (2018/10) @krjakbrjak (2023/02) @fa0311 (2023/10) @multani (2023/10)