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
22k stars 6.6k forks source link

[BUG] [PYTHON] A schema named Schema with type array generates broken model null<SchemaInner> in 7.2, works in 6.0 #17755

Open doctorpangloss opened 10 months ago

doctorpangloss commented 10 months ago

Bug Report Checklist

Description
    QueueTuple:
      type: array
      description: ...
      items:
        oneOf:
          - type: number
          - type: string
          - $ref: "#/components/schemas/Prompt"
          - $ref: "#/components/schemas/ExtraData"

A schema of type: array with a oneOf in items produces snippets of broken Python code like:

from comfy.api.models.null<queue_tuple_inner> import null<QueueTupleInner>
...

class QueueTuple(null<QueueTupleInner>):
    """
    The first item is the queue priority The second item is the hash id of the prompt object The third item is a Prompt The fourth item is optionally an ExtraData The fifth item is optionally a list of \"Good Outputs\" node IDs. 
    """ # noqa: E501
    __properties: ClassVar[List[str]] = []
   ...
openapi-generator version

7.2.0 (regression compared to 6.x)

OpenAPI declaration file content or url

https://github.com/hiddenswitch/ComfyUI/blob/wip/api/comfy/api/openapi.yaml

Logs on 7.3.0 (master):

``` [main] INFO o.o.codegen.DefaultGenerator - Generating with dryRun=false [main] INFO o.o.c.ignore.CodegenIgnoreProcessor - No .openapi-generator-ignore file found. [main] INFO o.o.codegen.DefaultGenerator - OpenAPI Generator: python (client) [main] INFO o.o.codegen.DefaultGenerator - Generator 'python' is considered stable. [main] INFO o.o.c.l.AbstractPythonCodegen - Environment variable PYTHON_POST_PROCESS_FILE not defined so the Python code may not be properly formatted. To define it, try 'export PYTHON_POST_PROCESS_FILE="/usr/local/bin/yapf -i"' (Linux/Mac) [main] INFO o.o.c.l.AbstractPythonCodegen - NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI). [main] INFO o.o.c.languages.PythonClientCodegen - Environment variable PYTHON_POST_PROCESS_FILE not defined so the Python code may not be properly formatted. To define it, try 'export PYTHON_POST_PROCESS_FILE="/usr/local/bin/yapf -i"' (Linux/Mac) [main] INFO o.o.c.languages.PythonClientCodegen - NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as upload_image_request. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings upload_image_request=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings upload_image_request=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as upload_image_200_response. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings upload_image_200_response=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings upload_image_200_response=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as get_prompt_200_response_exec_info. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings get_prompt_200_response_exec_info=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings get_prompt_200_response_exec_info=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as get_prompt_200_response. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings get_prompt_200_response=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings get_prompt_200_response=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as get_history_200_response_value. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings get_history_200_response_value=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings get_history_200_response_value=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as post_history_request. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings post_history_request=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings post_history_request=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as get_queue_200_response. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings get_queue_200_response=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings get_queue_200_response=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as _api_v1_prompts_post_request. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings _api_v1_prompts_post_request=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings _api_v1_prompts_post_request=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as _api_v1_prompts_post_200_response. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings _api_v1_prompts_post_200_response=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings _api_v1_prompts_post_200_response=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as Node_input_required_value_inner_oneOf. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings Node_input_required_value_inner_oneOf=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings Node_input_required_value_inner_oneOf=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as Node_input_required_value_inner. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings Node_input_required_value_inner=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings Node_input_required_value_inner=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as Node_input. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings Node_input=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings Node_input=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as ExtraData_extra_pnginfo. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings ExtraData_extra_pnginfo=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings ExtraData_extra_pnginfo=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as PromptNode_inputs_value_oneOf_inner. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings PromptNode_inputs_value_oneOf_inner=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings PromptNode_inputs_value_oneOf_inner=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as PromptNode_inputs_value. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings PromptNode_inputs_value=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings PromptNode_inputs_value=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as PromptNode_is_changed. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings PromptNode_is_changed=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings PromptNode_is_changed=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as Workflow_nodes_inner_size. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings Workflow_nodes_inner_size=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings Workflow_nodes_inner_size=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as Workflow_nodes_inner_inputs_inner. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings Workflow_nodes_inner_inputs_inner=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings Workflow_nodes_inner_inputs_inner=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as Workflow_nodes_inner_outputs_inner. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings Workflow_nodes_inner_outputs_inner=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings Workflow_nodes_inner_outputs_inner=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as Workflow_nodes_inner. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings Workflow_nodes_inner=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings Workflow_nodes_inner=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as Workflow_links_inner_inner. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings Workflow_links_inner_inner=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings Workflow_links_inner_inner=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.InlineModelResolver - Inline schema created as QueueTuple_inner. To have complete control of the model name, set the `title` field or use the modelNameMapping option (e.g. --model-name-mappings QueueTuple_inner=NewModel,ModelA=NewModelA in CLI) or inlineSchemaNameMapping option (--inline-schema-name-mappings QueueTuple_inner=NewModel,ModelA=NewModelA in CLI). [main] INFO o.o.codegen.DefaultGenerator - Model upload_image_request not generated since it's marked as unused (due to form parameters) and `skipFormModel` (global property) set to true (default) [main] WARN o.o.c.l.AbstractPythonCodegen - Codegen property is null (e.g. map/dict of undefined type). Default to typing.Any. [main] WARN o.o.c.l.AbstractPythonCodegen - Codegen property is null (e.g. map/dict of undefined type). Default to typing.Any. [main] WARN o.o.c.l.AbstractPythonCodegen - Codegen property is null (e.g. map/dict of undefined type). Default to typing.Any. [main] WARN o.o.c.l.AbstractPythonCodegen - Codegen property is null (e.g. map/dict of undefined type). Default to typing.Any. [main] WARN o.o.c.l.AbstractPythonCodegen - Codegen property is null (e.g. map/dict of undefined type). Default to typing.Any. [main] WARN o.o.c.l.AbstractPythonCodegen - Codegen property is null (e.g. map/dict of undefined type). Default to typing.Any. [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\api_v1_prompts_post200_response.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_api_v1_prompts_post200_response.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\ApiV1PromptsPost200Response.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\api_v1_prompts_post_request.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_api_v1_prompts_post_request.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\ApiV1PromptsPostRequest.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\extra_data.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_extra_data.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\ExtraData.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\extra_data_extra_pnginfo.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_extra_data_extra_pnginfo.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\ExtraDataExtraPnginfo.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\get_history200_response_value.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_get_history200_response_value.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\GetHistory200ResponseValue.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\get_prompt200_response.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_get_prompt200_response.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\GetPrompt200Response.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\get_prompt200_response_exec_info.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_get_prompt200_response_exec_info.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\GetPrompt200ResponseExecInfo.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\get_queue200_response.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_get_queue200_response.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\GetQueue200Response.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\node.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_node.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\Node.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\node_input.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_node_input.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\NodeInput.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\node_input_required_value_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_node_input_required_value_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\NodeInputRequiredValueInner.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\node_input_required_value_inner_one_of.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_node_input_required_value_inner_one_of.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\NodeInputRequiredValueInnerOneOf.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\post_history_request.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_post_history_request.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\PostHistoryRequest.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\prompt.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_prompt.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\Prompt.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\prompt_node.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_prompt_node.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\PromptNode.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\prompt_node_inputs_value.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_prompt_node_inputs_value.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\PromptNodeInputsValue.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\prompt_node_inputs_value_one_of_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_prompt_node_inputs_value_one_of_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\PromptNodeInputsValueOneOfInner.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\prompt_node_is_changed.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_prompt_node_is_changed.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\PromptNodeIsChanged.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\prompt_request.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_prompt_request.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\PromptRequest.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\queue_tuple.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_queue_tuple.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\QueueTuple.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\queue_tuple_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_queue_tuple_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\QueueTupleInner.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\upload_image200_response.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_upload_image200_response.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\UploadImage200Response.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\workflow.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_workflow.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\Workflow.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\workflow_links_inner_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_workflow_links_inner_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\WorkflowLinksInnerInner.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\workflow_nodes_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_workflow_nodes_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\WorkflowNodesInner.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\workflow_nodes_inner_inputs_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_workflow_nodes_inner_inputs_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\WorkflowNodesInnerInputsInner.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\workflow_nodes_inner_outputs_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_workflow_nodes_inner_outputs_inner.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\WorkflowNodesInnerOutputsInner.md [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\models\workflow_nodes_inner_size.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\test\test_workflow_nodes_inner_size.py [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\docs\WorkflowNodesInnerSize.md [main] INFO o.o.codegen.DefaultGenerator - Skipping generation of APIs. [main] INFO o.o.codegen.DefaultGenerator - Skipping generation of Webhooks. [main] INFO o.o.codegen.TemplateManager - Skipped .\comfy\api_README.md (Skipped by supportingFiles options supplied by user.) [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\configuration.py [main] INFO o.o.codegen.TemplateManager - Skipped .\comfy\api\__init__.py (Skipped by supportingFiles options supplied by user.) [main] INFO o.o.codegen.TemplateManager - Skipped .\comfy\api\models\__init__.py (Skipped by supportingFiles options supplied by user.) [main] INFO o.o.codegen.TemplateManager - Skipped .\comfy\api\api\__init__.py (Skipped by supportingFiles options supplied by user.) [main] INFO o.o.codegen.TemplateManager - Skipped .\comfy\__init__.py (Skipped by supportingFiles options supplied by user.) [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\exceptions.py [main] INFO o.o.codegen.TemplateManager - Skipped .\comfy\api\test\__init__.py (Skipped by supportingFiles options supplied by user.) [main] INFO o.o.codegen.TemplateManager - Skipped .\comfy\api\api_client.py (Skipped by supportingFiles options supplied by user.) [main] INFO o.o.codegen.TemplateManager - writing file .\comfy\api\api_response.py [main] INFO o.o.codegen.TemplateManager - Skipped .\comfy\api\rest.py (Skipped by supportingFiles options supplied by user.) [main] INFO o.o.codegen.TemplateManager - Skipped .\.openapi-generator-ignore (Skipped by supportingFiles options supplied by user.) [main] INFO o.o.codegen.TemplateManager - writing file ./\.openapi-generator\VERSION [main] INFO o.o.codegen.TemplateManager - writing file ./\.openapi-generator\FILES ################################################################################ # Thanks for using OpenAPI Generator. # # Please consider donation to help us maintain this project ? # # https://opencollective.com/openapi_generator/donate # ################################################################################ ```
Generation Details

openapi_python_config.yaml:

inputSpec: ./openapi.yaml
outputDir: ./
generatorName: python
globalProperties:
  supportingFiles:
    - "schemas.py"
    - "exceptions.py"
    - "configuration.py"
    - "api_response.py"
additionalProperties:
  generateSourceCodeOnly: true
  packageName: comfy.api
  generateAliasAsModel: true
java --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED -jar openapi-generator-cli-7.2.0.jar generate --input-spec ./comfy/api/openapi.yaml --global-property models --config ./comfy/api/openapi_python_config.yaml
Steps to reproduce

See Collab notebook here https://colab.research.google.com/drive/18sXET4mnQLMrsxru2vumN7iuk1fVJEVr?usp=sharing

git clone https://github.com/hiddenswitch/ComfyUI.git --branch wip/api repro
git clone https://github.com/OpenAPITools/openapi-generator.git --depth=1
(cd openapi-generator && ./mvnw clean install -Dmaven.test.skip=true -Dmaven.javadoc.skip=true -q &>/dev/null)
(cd repro && java --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED -jar ../openapi-generator/modules/openapi-generator-cli/target/openapi-generator-cli.jar generate --input-spec ./comfy/api/openapi.yaml --global-property models --config ./comfy/api/openapi_python_config.yaml)

cat ./repro/comfy/api/models/queue_tuple.py

Observe queue_tuple has content like

from comfy.api.models.null<queue_tuple_inner> import null<QueueTupleInner>
from typing import Optional, Set
from typing_extensions import Self

class QueueTuple(null<QueueTupleInner>)

which is not valid Python and indicates a bug.

Related issues/PRs

Related to https://github.com/OpenAPITools/openapi-generator/issues/17745

Suggest a fix

Not sure what the underlying issue is, are Array schemas unexpected? this works in 6.x.

wing328 commented 10 months ago

generateAliasAsModel: true

can you try setting it to false instead?

doctorpangloss commented 9 months ago

This causes other errors:

....
[main] INFO  o.o.codegen.DefaultGenerator - Model Prompt not generated since it's a free-form object
[main] INFO  o.o.codegen.DefaultGenerator - Model Outputs not generated since it's a free-form object
[main] INFO  o.o.codegen.DefaultGenerator - Model upload_image_request not generated since it's marked as unused (due to form parameters) and `skipFormModel` (global property) set to true (default)
[main] WARN  o.o.c.l.AbstractPythonCodegen - Failed to lookup model in createImportMapOfSet Dict[str, PromptNode]
[main] WARN  o.o.c.l.AbstractPythonCodegen - Failed to lookup model in createImportMapOfSet Dict[str, Output]
[main] WARN  o.o.c.l.AbstractPythonCodegen - Failed to lookup model in createImportMapOfSet Dict[str, PromptNode]
[main] WARN  o.o.c.l.AbstractPythonCodegen - Codegen property is null (e.g. map/dict of undefined type). Default to typing.Any.
[main] WARN  o.o.c.l.AbstractPythonCodegen - Codegen property is null (e.g. map/dict of undefined type). Default to typing.Any.
[main] WARN  o.o.c.l.AbstractPythonCodegen - Codegen property is null (e.g. map/dict of undefined type). Default to typing.Any.
...

No... these are maps with typed values. This must be a bug. See the updated colab here: https://github.com/OpenAPITools/openapi-generator/issues/17755#issuecomment-1920919909

mharding-hpe commented 1 week ago

I am seeing this problem with version 7.10.0 with every schema of type array.

mharding-hpe commented 1 week ago

The following openapi file reproduces the bug:

openapi: "3.0.3"
info:
  title: "Bug example"
  version: "1.2.3"
  description: Demonstrating issue 17755 
components:
  schemas:
    StringList:
      description: List of strings
      type: array
      items:
        type: string
paths: {}

I generate the code with the following:

podman run -v $(pwd):/harf docker.io/openapitools/openapi-generator-cli:v7.10.0 generate -i /harf/openapi.yaml -g python -o /harf/17755 --generate-alias-as-model

It succeeds, but in the output, I do see the following:

[main] WARN  o.o.codegen.utils.ModelUtils - Failed to get the schema name: null

And in the generated model code:

from pydantic import ConfigDict, RootModel
from typing import Any, ClassVar, Dict, List
from openapi_client.models.null<str> import null<str>
from typing import Optional, Set
from typing_extensions import Self

class StringList(null<str>):
mharding-hpe commented 1 week ago

Further testing confirms that this bug does not exist in v6.6.0 but exists in v7.0.0 (and v7.0.0-beta)

mharding-hpe commented 1 week ago

In the last version where the bug did not exist, the corresponding lines of the Python model were:

import typing  # noqa: F401
import typing_extensions  # noqa: F401
import uuid  # noqa: F401

import frozendict  # noqa: F401

from openapi_client import schemas  # noqa: F401

class StringList(
    schemas.ListSchema
):
mharding-hpe commented 1 week ago

I misspoke. I made the mistake of using the python generator when I was using v6.6.0. However, I was reviewing the release notes for v7.0.0-beta, and I noticed this:

Rename python-nextgen to python by @wing328 in https://github.com/OpenAPITools/openapi-generator/pull/15504

And when I use python-nextgen with v6.6.0, the bug still occurs.

So this only gives the appearance of being a regression between v6 and v7 -- in fact, this problem already existed in v6, but the renaming of the generators masked that fact.

mharding-hpe commented 1 week ago

Looking further back, I can see that the python-nextgen generator was added new in v6.3.0, and this bug exists there. So as best I can tell, this bug has always existed with this generator.

I was hoping to find out when this broke, so I could try and see if I could spot what caused it, but no such luck. I am not familiar with the source code for this tool, so further investigation will be slow going. But unless I am mistaken, all array models are broken with this generator.

mharding-hpe commented 1 week ago

In case it is helpful, I built openapi-generator locally, but uncommented these commented throw statements. This is the resulting stack trace when generating:

[main] WARN  o.o.codegen.utils.ModelUtils - Failed to get the schema name: null
[main] ERROR o.o.codegen.DefaultGenerator - An exception occurred in OpenAPI Normalizer. Please report the issue via https://github.com/openapitools/openapi-generator/issues/new/:
[main] ERROR o.o.codegen.DefaultGenerator - An exception occurred in OpenAPI Normalizer. Please report the issue via https://github.com/openapitools/openapi-generator/issues/new/:
java.lang.RuntimeException: Failed to get the schema: null
        at org.openapitools.codegen.utils.ModelUtils.getSimpleRef(ModelUtils.java:387)
        at org.openapitools.codegen.OpenAPINormalizer.isSelfReference(OpenAPINormalizer.java:581)
        at org.openapitools.codegen.OpenAPINormalizer.fixSelfReferenceSchema(OpenAPINormalizer.java:547)
        at org.openapitools.codegen.OpenAPINormalizer.normalizeComponentsSchemas(OpenAPINormalizer.java:517)
        at org.openapitools.codegen.OpenAPINormalizer.normalize(OpenAPINormalizer.java:299)
        at org.openapitools.codegen.DefaultGenerator.configureGeneratorProperties(DefaultGenerator.java:275)
        at org.openapitools.codegen.DefaultGenerator.generate(DefaultGenerator.java:1288)
        at org.openapitools.codegen.cmd.Generate.execute(Generate.java:535)
        at org.openapitools.codegen.cmd.OpenApiGeneratorCommand.run(OpenApiGeneratorCommand.java:32)
        at org.openapitools.codegen.OpenAPIGenerator.main(OpenAPIGenerator.java:66)
wing328 commented 1 week ago

@mharding-hpe did you try the latest stable version v7.10.0 released a few days ago?

mharding-hpe commented 1 week ago

@wing328 yes, the bug exists there as well. It also exists in the latest master branch (as of yesterday, anyway).

mharding-hpe commented 4 days ago

This same bug happens with the python-fastapi and python-pydantic-v1 generators.

It does not happen with python-aiohttp, python-blueplanet, or python-flask.

(all of the above verified with v7.10.0, using the same test to reproduce as in my earlier comment)

mharding-hpe commented 3 days ago

In addition to the problems with the array model that I noted earlier, there are some other things that look wrong (although they are not syntax errors like the problem noted before). Namely, the model defines the to_dict and from_dict methods, which don't make sense for an array:

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of StringList from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
        })
        return _obj

I note that models for other primitive types (like enumerated strings) don't have those methods. So I suspect the fact that they are present here is further indication that the code which generates models has some kind of blind spot in terms of handling arrays.

In my forays into the source code, I do see various places where it has checks to see if the schema being handled is an array or not. But some logic in the generator is missing somewhere to ensure that the correct models are generated.

I was also curious to see if I could figure out what the "right" model would even look like for this case. I think the following changes would be needed:

  1. Add RootModel to the import list from pydantic
  2. Remove the import line from openapi_client.models.null<str> import null<str> (although a line like this would be needed if the array was of schemas, rather than of primitive strings).
  3. Change the class declaration to class StringList(RootModel[List[str]]):
  4. Remove the to_dict and from_dict methods.

The only other thing I'm not sure of is whether or not we'd need/want to_list and from_list methods. It seems like they'd make sense.