Skip to content

Incorrect type definition order #2508

@forman

Description

@forman

Describe the bug

First of all, thank you for this wonderful tool. It saved me so much time already. However, today I spend a few hours with it and no success.

I'm generating pydantic V2 models from my openapi.yaml. The Python module is generated without errors. But after I had to change the component schemas in my openapi.yaml the generated module can no longer be imported because the types are defined in the wrong order.

I found the keep_model_order=True flag, and I suppose its meaning is that the order of generated types will be the one of the component definitions in my openapi.yaml file, but the opposite is the case.

To Reproduce

Example schema:

--> See below, so the issue remains readable.

Used commandline:

--> I used the generate() function. The call is also below.

Expected behavior

  • keep_model_order=True: Generated types should have exactly the order from the schema.
  • keep_model_order=False: The produced order should automatically resolve type dependencies correctly.

Version:

  • OS: All
  • Python version: 3.13.5
  • datamodel-code-generator version: 0.30.0

Additional context

I'd actually like to be able to provide my own pydantic types to the generator, see #2243.

generate() call:

import datamodel_code_generator as dcg

def main():
    dcg.generate(
        input_="openapi.yaml",
        input_file_type=dcg.InputFileType.OpenAPI,
        use_annotated=True,
        use_double_quotes=True,
        use_standard_collections=True,
        use_schema_description=True,
        use_non_positive_negative_number_constrained_types=True,
        use_title_as_name=True,
        use_one_literal_as_default=True,
        use_union_operator=False,
        field_constraints=True,
        set_default_enum_member=True,
        keep_model_order=False,  # --> BUG: True will sort types
        target_python_version=dcg.PythonVersion.PY_310,
        output_model_type=dcg.DataModelType.PydanticV2BaseModel,
        output="models.py",
    )

if __name__ == "__main__":
    main()

openapi.yaml:

openapi: 3.0.3
info:
  title: "S2GOS web API"
  description: "S2GOS API conforming to version 1.0.0 of the [OGC API - Processes - Part 1: Core](https://docs.ogc.org/is/18-062r2/18-062r2.html) Standard.\n\n  Copyright (c) 2021 Open Geospatial Consortium.\n\n  To obtain additional rights of use, visit http://www.opengeospatial.org/legal/ \n\n  This document is an API definition document provided alongside the  OGC API - Processes standard. The OGC API - Processes Standard specifies a processing  interface to communicate over a RESTful protocol using JavaScript Object Notation  (JSON) encodings. The specification allows for the wrapping of computational tasks  into executable processes that can be offered by a server and be invoked by a  client application."
  contact:
    name: S2GOS development team
    url: https://s2gos-dev.github.io
  license:
    name: Apache 2.0 license
    url: http://www.apache.org/licenses/LICENSE-2.0
  version: 1.0.0
servers:
- url: http://localhost:8008
  description: Local S2GOS demo server
paths:
  /:
    get:
      tags:
      - Capabilities
      summary: landing page of this API
      description: |-
        The landing page provides links to the:
          * The OpenAPI-definition (no fixed path),
          * The Conformance statements (path /conformance),
          * The processes metadata (path /processes),
          * The endpoint for job monitoring (path /jobs).

        For more information, see [Section 7.2](https://docs.ogc.org/is/18-062/18-062.html#sc_landing_page).
      operationId: getCapabilities
      responses:
        "200":
          description: |-
            The landing page provides links to the API definition
            (link relations `service-desc` and `service-doc`),
            the Conformance declaration (path `/conformance`,
            link relation `http://www.opengis.net/def/rel/ogc/1.0/conformance`), and to other resources.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Capabilities'
            text/html:
              schema:
                type: string
        "500":
          description: A server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
  /conformance:
    get:
      tags:
      - ConformanceDeclaration
      summary: information about standards that this API conforms to
      description: |
        A list of all conformance classes, specified in a standard, that the server conforms to.

        | Conformance class | URI |
        |-----------|-------|
        |Core|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core|
        |OGC Process Description|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/ogc-process-description|
        |JSON|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/json|
        |HTML|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/html|
        |OpenAPI Specification 3.0|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/oas30|
        |Job list|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/job-list|
        |Callback|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/callback|
        |Dismiss|http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/dismiss|

        For more information, see [Section 7.4](https://docs.ogc.org/is/18-062/18-062.html#sc_conformance_classes).
      operationId: getConformance
      responses:
        "200":
          description: |-
            The URIs of all conformance classes supported by the server.

            To support "generic" clients that want to access multiple
            OGC API - Processes implementations - and not "just" a specific
            API / server, the server declares the conformance
            classes it implements and conforms to.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConformanceDeclaration'
              example:
                conformsTo:
                - http://www.opengis.net/spec/ogcapi-processes/1.0/conf/core
            text/html:
              schema:
                type: string
        "500":
          description: A server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
  /processes:
    get:
      tags:
      - ProcessList
      summary: retrieve the list of available processes
      description: |
        The list of processes contains a summary of each process the OGC API - Processes offers, including the link to a more detailed description of the process.

        For more information, see [Section 7.9](https://docs.ogc.org/is/18-062/18-062.html#sc_process_list).
      operationId: getProcesses
      responses:
        "200":
          description: Information about the available processes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProcessList'
  /processes/{processID}:
    get:
      tags:
      - ProcessDescription
      summary: retrieve a process description
      description: |
        The process description contains information about inputs and outputs and a link to the execution-endpoint for the process. The Core does not mandate the use of a specific process description to specify the interface of a process. That said, the Core requirements class makes the following recommendation:

        Implementations SHOULD consider supporting the OGC process description.

        For more information, see [Section 7.10](https://docs.ogc.org/is/18-062/18-062.html#sc_process_description).
      operationId: getProcess
      parameters:
      - name: processID
        in: path
        required: true
        schema:
          type: string
      responses:
        "200":
          description: A process description.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProcessDescription'
              examples:
                description:
                  summary: A Process Description example
                  externalValue: ../../examples/json/ProcessDescription.json
        "404":
          description: The requested URI was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
  /processes/{processID}/execution:
    post:
      tags:
      - ProcessRequest
      - InlineValue
      - JobInfo
      summary: execute a process.
      description: |
        Create a new job.

        For more information, see [Section 7.11](https://docs.ogc.org/is/18-062/18-062.html#sc_create_job).
      operationId: executeProcess
      parameters:
      - name: processID
        in: path
        required: true
        schema:
          type: string
      requestBody:
        description: Mandatory request JSON
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProcessRequest'
        required: true
      responses:
        "200":
          description: Result of synchronous execution
          content:
            /*:
              schema:
                $ref: '#/components/schemas/InlineValue'
        "201":
          description: Started asynchronous execution. Created job.
          headers:
            Location:
              description: URL to check the status of the execution/job.
              schema:
                type: string
            Preference-Applied:
              description: The preference applied to execute the process asynchronously (see. RFC 2740).
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobInfo'
        "404":
          description: The requested URI was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
        "500":
          description: A server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
      callbacks:
        jobCompleted:
          '{$request.body#/subscriber/successUri}':
            post:
              requestBody:
                content:
                  application/json:
                    schema:
                      $ref: '#/components/schemas/JobResults'
              responses:
                "200":
                  description: Results received successfully
  /jobs:
    get:
      tags:
      - JobList
      summary: retrieve the list of jobs.
      description: |
        Lists available jobs.

        For more information, see [Section 11](https://docs.ogc.org/is/18-062/18-062.html#sc_job_list).
      operationId: getJobs
      responses:
        "200":
          description: A list of jobs for this process.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobList'
        "404":
          description: The requested URI was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
  /jobs/{jobId}:
    get:
      tags:
      - JobStatus
      summary: retrieve the status of a job
      description: |
        Shows the status of a job.

        For more information, see [Section 7.12](https://docs.ogc.org/is/18-062/18-062.html#sc_retrieve_status_info).
      operationId: getJob
      parameters:
      - name: jobId
        in: path
        description: local identifier of a job
        required: true
        schema:
          type: string
      responses:
        "200":
          description: The status of a job.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobInfo'
        "404":
          description: The requested URI was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
        "500":
          description: A server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
    delete:
      tags:
      - Dismiss
      summary: "cancel a job execution, remove a finished job"
      description: |
        Cancel a job execution and remove it from the jobs list.

        For more information, see [Section 13](https://docs.ogc.org/is/18-062/18-062.html#Dismiss).
      operationId: dismissJob
      parameters:
      - name: jobId
        in: path
        description: local identifier of a job
        required: true
        schema:
          type: string
      responses:
        "200":
          description: Information about the job.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobInfo'
        "404":
          description: The requested URI was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
        "500":
          description: A server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
  /jobs/{jobId}/results:
    get:
      tags:
      - JobResults
      summary: retrieve the result(s) of a job
      description: |
        Lists available results of a job. In case of a failure, lists errors instead.

        For more information, see [Section 7.13](https://docs.ogc.org/is/18-062/18-062.html#sc_retrieve_job_results).
      operationId: getJobResults
      parameters:
      - name: jobId
        in: path
        description: local identifier of a job
        required: true
        schema:
          type: string
      responses:
        "200":
          description: The results of a job.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobResults'
        "404":
          description: The requested URI was not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
        "500":
          description: A server error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
            text/html:
              schema:
                type: string
components:
  schemas:
    #------------------------------------------------------
    # Generic low-level objects
    #------------------------------------------------------
    CRS:
      type: string
      format: uri
      default: http://www.opengis.net/def/crs/OGC/1.3/CRS84
      enum:
      - http://www.opengis.net/def/crs/OGC/1.3/CRS84
      - http://www.opengis.net/def/crs/OGC/0/CRS84h
    ApiError:
      required:
      - type
      type: object
      properties:
        type:
          type: string
        title:
          type: string
        status:
          type: integer
        detail:
          type: string
        instance:
          type: string
        # Extension of OGC API / Processes core v1
        traceback:
          type: array
          items:
            type: string
      additionalProperties: true
      description: API error based on RFC 7807
    MaxOccurs:
      type: string
      enum:
      - unbounded
    InlineValue:
      oneOf:
      - nullable: true
      - type: boolean
      - type: string
        format: binary
      - type: string
        format: uri
      - type: string
        format: date
      - type: string
        format: date-time
      - type: string
      - type: integer
      - type: number
      - type: array
      - type: object
      - $ref: '#/components/schemas/Bbox'
    Format:
      type: object
      properties:
        mediaType:
          type: string
        encoding:
          type: string
        schema:
          oneOf:
          - type: string
            format: uri
          - $ref: '#/components/schemas/Schema'
    Link:
      required:
      - href
      type: object
      properties:
        href:
          type: string
        rel:
          type: string
          example: service
        type:
          type: string
          example: application/json
        hreflang:
          type: string
          example: en
        title:
          type: string
    QualifiedValue:
      allOf:
      - $ref: '#/components/schemas/Format'
      - type: object
        required:
        - value
        properties:
          value:
            $ref: '#/components/schemas/InlineValue'
    InlineOrRefValue:
      oneOf:
      - $ref: '#/components/schemas/InlineValue'
      - $ref: '#/components/schemas/QualifiedValue'
      - $ref: '#/components/schemas/Link'
    Bbox:
      type: object
      required:
      - bbox
      properties:
        bbox:
          type: array
          minItems: 4
          maxItems: 4
          items:
            type: number
        crs:
          $ref: '#/components/schemas/CRS'
    DescriptionType:
      type: object
      properties:
        title:
          type: string
        description:
          type: string
        keywords:
          type: array
          items:
            type: string
        metadata:
          type: array
          items:
            $ref: '#/components/schemas/Metadata'
        additionalParameters:
          allOf:
          - $ref: '#/components/schemas/Metadata'
          - type: object
            properties:
              parameters:
                type: array
                items:
                  $ref: '#/components/schemas/AdditionalParameter'
    DataType:
      type: string
      enum:
      - array
      - boolean
      - integer
      - number
      - object
      - string
    Schema:
      type: object
      properties:
        $ref:
          type: string
          format: uri-reference
        title:
          type: string
        multipleOf:
          minimum: 0
          exclusiveMinimum: true
          type: number
        maximum:
          type: number
        exclusiveMaximum:
          type: boolean
          default: false
        minimum:
          type: number
        exclusiveMinimum:
          type: boolean
          default: false
        maxLength:
          minimum: 0
          type: integer
        minLength:
          minimum: 0
          type: integer
          default: 0
        pattern:
          type: string
          format: regex
        maxItems:
          minimum: 0
          type: integer
        minItems:
          minimum: 0
          type: integer
          default: 0
        uniqueItems:
          type: boolean
          default: false
        maxProperties:
          minimum: 0
          type: integer
        minProperties:
          minimum: 0
          type: integer
          default: 0
        required:
          minItems: 1
          uniqueItems: true
          type: array
          items:
            type: string
        enum:
          minItems: 1
          uniqueItems: false
          type: array
          items:
            type: object
        type:
          $ref: '#/components/schemas/DataType'
        not:
          $ref: '#/components/schemas/Schema'
        allOf:
          type: array
          items:
            $ref: '#/components/schemas/Schema'
        oneOf:
          type: array
          items:
            $ref: '#/components/schemas/Schema'
        anyOf:
          type: array
          items:
            $ref: '#/components/schemas/Schema'
        discriminator:
          type: object
          properties:
            propertyName:
              type: string
              minLength: 1
            mapping:
              type: object
              additionalProperties:
                $ref: '#/components/schemas/Schema'
        items:
          oneOf:
          - type: array
            items:
              $ref: '#/components/schemas/Schema'
          - $ref: '#/components/schemas/Schema'
        properties:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Schema'
        additionalProperties:
          oneOf:
          - $ref: '#/components/schemas/Schema'
          - type: boolean
          default: true
        description:
          type: string
        format:
          type: string
        default: {}
        nullable:
          type: boolean
          default: false
        readOnly:
          type: boolean
          default: false
        writeOnly:
          type: boolean
          default: false
        example: {}
        examples: {}
        deprecated:
          type: boolean
          default: false
        contentMediaType:
          type: string
        contentEncoding:
          type: string
        contentSchema:
          type: string
      additionalProperties: false
    Metadata:
      type: object
      properties:
        title:
          type: string
        role:
          type: string
        href:
          type: string
    AdditionalParameter:
      required:
      - name
      - value
      type: object
      properties:
        name:
          type: string
        value:
          type: array
          items:
            oneOf:
            - type: string
            - type: number
            - type: integer
            - type: array
              items:
                type: object
            - type: object
    TransmissionMode:
      type: string
      default: value
      enum:
      - value
      - reference
    #------------------------------------------------------
    # Thematic objects
    #------------------------------------------------------
    Capabilities:
      required:
      - links
      type: object
      properties:
        title:
          type: string
          example: Example processing server
        description:
          type: string
          example: Example server implementing the OGC API - Processes 1.0 Standard
        links:
          type: array
          items:
            $ref: '#/components/schemas/Link'
    ConformanceDeclaration:
      required:
      - conformsTo
      type: object
      properties:
        conformsTo:
          type: array
          items:
            type: string
            example: http://www.opengis.net/spec/ogcapi-processes-1/1.0/conf/core
    ProcessList:
      required:
      - links
      - processes
      type: object
      properties:
        processes:
          type: array
          items:
            $ref: '#/components/schemas/ProcessSummary'
        links:
          type: array
          items:
            $ref: '#/components/schemas/Link'
    ProcessDescription:
      allOf:
      - $ref: '#/components/schemas/ProcessSummary'
      - type: object
        properties:
          inputs:
            type: object
            additionalProperties:
              $ref: '#/components/schemas/InputDescription'
          outputs:
            type: object
            additionalProperties:
              $ref: '#/components/schemas/OutputDescription'
    ProcessRequest:
      type: object
      properties:
        inputs:
          type: object
          additionalProperties:  {}
        outputs:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/Output'
        response:
          $ref: '#/components/schemas/ResponseType'
        subscriber:
          $ref: '#/components/schemas/Subscriber'
    ProcessSummary:
      allOf:
      - $ref: '#/components/schemas/DescriptionType'
      - required:
        - id
        - version
        type: object
        properties:
          id:
            type: string
          version:
            type: string
          jobControlOptions:
            type: array
            items:
              $ref: '#/components/schemas/JobControlOptions'
          outputTransmission:
            type: array
            items:
              $ref: '#/components/schemas/TransmissionMode'
          links:
            type: array
            items:
              $ref: '#/components/schemas/Link'
    InputDescription:
      allOf:
      - $ref: '#/components/schemas/DescriptionType'
      - required:
        - schema
        type: object
        properties:
          minOccurs:
            type: integer
            default: 1
          maxOccurs:
            oneOf:
            - type: integer
              default: 1
            - $ref: '#/components/schemas/MaxOccurs'
          schema:
            $ref: '#/components/schemas/Schema'
    OutputDescription:
      allOf:
      - $ref: '#/components/schemas/DescriptionType'
      - required:
        - schema
        type: object
        properties:
          schema:
            $ref: '#/components/schemas/Schema'
    Output:
      type: object
      properties:
        format:
          $ref: '#/components/schemas/Format'
        transmissionMode:
          $ref: '#/components/schemas/TransmissionMode'
    ResponseType:
      type: string
      default: raw
      enum:
      - raw
      - document
    Subscriber:
      required:
      - successUrl
      type: object
      properties:
        successUri:
          type: string
          format: uri
        inProgressUri:
          type: string
          format: uri
        failedUri:
          type: string
          format: uri
      description: |-
        Optional URIs for callbacks for this job.

        Support for this parameter is not required and the parameter may be
        removed from the API definition, if conformance class **'callback'**
        is not listed in the conformance declaration under `/conformance`.
    JobStatus:
      type: string
      nullable: false
      enum:
      - accepted
      - running
      - successful
      - failed
      - dismissed
    JobType:
      type: string
      enum:
      - process
    JobControlOptions:
      type: string
      enum:
      - sync-execute
      - async-execute
      - dismiss
    JobList:
      required:
      - jobs
      - links
      type: object
      properties:
        jobs:
          type: array
          items:
            $ref: '#/components/schemas/JobInfo'
        links:
          type: array
          items:
            $ref: '#/components/schemas/Link'
    JobInfo:
      required:
      - jobID
      - status
      - type
      type: object
      properties:
        processID:
          type: string
        type:
          $ref: '#/components/schemas/JobType'
        jobID:
          type: string
        status:
          $ref: '#/components/schemas/JobStatus'
        message:
          type: string
        created:
          type: string
          format: date-time
        started:
          type: string
          format: date-time
        finished:
          type: string
          format: date-time
        updated:
          type: string
          format: date-time
        progress:
          maximum: 100
          minimum: 0
          type: integer
        links:
          type: array
          items:
            $ref: '#/components/schemas/Link'
        # Extension of OGC API / Processes core v1
        traceback:
          type: array
          items:
            type: string
    JobResults:
      type: object
      additionalProperties:
        $ref: '#/components/schemas/InlineOrRefValue'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions