Open kdipippo opened 7 months ago
Confirming that switching from:
ExampleField:
type:
oneOf:
- type: 'null'
description: This field is null when A, B, C
example: null
- type: string
description: Example string field.
example: "example"
to
ExampleField:
type:
- string
- 'null'
description: String when A, B, C. Null when X, Y, Z
example: "example"
Resulted in the client just generating the line:
example_field: Optional[StrictStr] = Field(default=None, description="String when A, B, C. Null when X, Y, Z", alias="ExampleField")
With none of the alternate-schemas code generated. This model is able to house the API responses.
Bug Report Checklist
Description
🟢 I found out a workaround while working on this, noted at the bottom. But figured I'd still file the steps here in case it's useful.
I'm working with taking a third party's API and writing an OAS file I can use to generate clients. Some of the fields in the API are nullable, including fields that normally return arrays of objects.
This
nullable string
property defined in OAS gets the following type-assertion block at the top of its python class:Meanwhile, this
nullable array of objects
property defined in OAS gets the following type-assertion block at the top of its python class:As a result, when I make an API call when
contents:
is notnull
, I get the error:Hit here because the result is matching true against both
oneof_schema_1_validator
andoneof_schema_2_validator
.Is there something I can do with the spec to clarify the differences between
contents:
's oneOfs? Also reporting this as a bug in caseoneof_schema_1_validator
should be checking againstOptional[List]
instead ofOptional[Any]
.openapi-generator version
OpenAPI declaration file content or url
Here's a full small sample spec that can generate the issue
```yaml openapi: 3.1.0 info: description: Example call to demo python generator version: v1 title: Python example contact: name: Example email: example@email.com url: https://example.com/ license: name: Example url: https://www.example.com/ tags: - name: ExampleCall description: Example Call Tag servers: - url: https://example.com/ paths: /api/v1/example: get: summary: Example call to demo python generator description: Example call to demo python generator security: - BearerAuth: [] tags: - ExampleCall operationId: getExampleCalls responses: "200": description: Successfully fetched items. content: application/json: schema: type: object properties: title: type: string description: Title example: "Example title" description: type: string description: Description example: "Example description" notes: oneOf: - type: string description: Notes textfield example: "Example notes attached to entity" - type: 'null' description: Null of no notes are set. contents: oneOf: - type: array description: Array of content objects items: type: object description: Content object properties: row-id: type: integer description: Row number inside table example: 1 name: type: string description: Name of content example: "Demo file" - type: 'null' description: Null if no contents are set. components: securitySchemes: BearerAuth: type: http scheme: bearer ```
Generation Details
NPM CLI generation
Latest snapshot generation (from today, Feb 23)
Steps to reproduce
I am not able to make the API I'm using available for this bug, but the payload returning from the API call is:
Setting up a test where the
ExampleCall
is mocked to return this output would reproduce the same error:Related issues/PRs
Mar 27, 2023 - This issue is around oneOf object and list(object) for the python-nextgen generator, which is kinda what the issue here is. I am not sure what command that user ran to build their client.
python-nextgen
is not a generator name, and I thinkpython
as the client generator is the latest version?No other issues within the past year tagged for Python seem to be related.
Suggest a fix
🟢 The workaround
Here's an alternate version of the OAS file where `oneOf`s are replaced with:
```yaml openapi: 3.1.0 info: description: Python OAS Client Generator Demos version: v1 title: Python example contact: name: Example email: example@email.com url: https://dummyurl.com license: name: Example url: https://www.dummyurl.com tags: - name: ExampleCall description: Example Call Tag servers: - url: https://dummyurl.com paths: /api/v1/example: get: summary: Example call to demo python generator description: This is an example to call to demo python generator security: - BearerAuth: [] tags: - ExampleCall operationId: getExampleCalls responses: "200": description: Successfully fetched items. content: application/json: schema: type: object properties: title: type: string description: Title example: "Example title" helpertext: type: string description: Description example: "Example description" notes: type: - string - 'null' description: Notes textfield. Null of no notes are set. example: "Example notes attached to entity" contents: type: - array - 'null' items: type: object description: Example of an inner object returned inside an array. Null if no contents are set. properties: row-id: type: integer description: Row number inside table example: 1 name: type: string description: Name of content example: "Demo file" example: row-id: 1 name: Demo file example: - row-id: 1 name: Demo file - row-id: 2 name: Another file example: title: Example title 1 helpertext: Example description 1 notes: Example notes contents: - row-id: 1 name: Demo file - row-id: 2 name: Another file examples: fullResult: value: title: Example title 1 helpertext: Example description 1 notes: Example notes contents: - row-id: 1 name: Demo file - row-id: 2 name: Another file blankArrayResult: summary: All fields are populated value: title: Example title 2 helpertext: Example description 2 notes: ~ contents: [] nullResult: summary: All fields are null value: title: Example title 3 helpertext: Example description 3 notes: ~ contents: ~ "404": description: API called incorrectly. content: application/json: schema: type: object properties: error: type: string description: Error message text example: "Error encountered" example: error: Error encountered examples: standardResult: summary: Usual result value: error: Error encountered components: securitySchemes: BearerAuth: type: http description: access_token after calling /connect/token endpoint. scheme: bearer ```
The resulting client generated in the same steps outlined above does create that
List[Object]
syntax assertion:So hypothetically, the handling exists already. But maybe the way that
oneOf
is set up in the structure makes it difficult to use in the same way as just the multipletype:
s.