[BUG][PYTHON] Using Openapi 3.0 Inheritance/Polymorphism keywords (allOf, anyOf, oneOf) causes generation of UNKNOWNBASETYPE model.
See original GitHub issueBug Report Checklist
- [y] Have you provided a full/minimal spec to reproduce the issue?
- [y] Have you validated the input using an OpenAPI validator (example)?
- [y] Have you tested with the latest master to confirm the issue still exists?
- [y] Have you searched for related issues/PRs?
- [y] What’s the actual output vs expected output?
- [maybe ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
Can’t use allof, anyof, or oneof keywords in request body → Will result in generating “UNKNOWNBASETYPE” which makes that client endpoint unusable. This is specific to Openapi 3.0. In Openapi 2.0 (swagger 2.0) one could get away with using “produces” and “consumes” (kubernetes api uses that) in POST requests. With Openapi 3.0, that has been replaced with requestBody and the use of the inheritance keywords (allOf, anyOf, oneOf). This problem also doesn’t seem specific to Python.
The following spec causes the issue:
OpenAPI declaration file content or url
openapi: 3.0.0
info:
title: Sample API
version: '2.0'
paths:
/v2/projects:
post:
operationId: create_project
summary: Create a Project
description: 'To create a project, send a POST request to `/v2/projects`.'
tags:
- Projects
requestBody:
required: true
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/project_base'
required:
- name
- purpose
responses:
'200':
description: OK
components:
schemas:
project_base:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
example: 4e1bfbc3
description: The unique universal identifier of this project.
name:
type: string
maxLength: 175
example: my-web-api
description: >-
The human-readable name for the project. The maximum length is 175
characters and the name must be unique.
description:
type: string
maxLength: 255
example: My website API
description: >-
The description of the project. The maximum length is 255
characters.
purpose:
type: string
maxLength: 255
example: Service or API
Generation Details
Generates a client that imports:
from openapi_client.model.unknownbasetype import UNKNOWNBASETYPE
and uses it in place of the schema described in requestbody (project_base).
If you rework the POST request as such to remove the use of allOf, you are able to create a POST request but you lose the ability to specify which properties are required for that specific endpoint:
paths:
/v2/projects:
post:
operationId: create_project
summary: Create a Project
description: 'To create a project, send a POST request to `/v2/projects`.'
tags:
- Projects
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/project_base'
responses:
'200':
description: OK
^This will generate the expected import statements in the client:
from openapi_client.model.project_base import ProjectBase
…but you lose the ability to specify which inherited properties are required for that specific endpoint). Also, if you were using oneOf or anyOf, I don’t think you’d be able to maintain their behavior with this workaround. I’ve seen people suggest creating a specific model for each endpoint and specify the required properties there, but that will cause the spec to be super clunky and generate weird model names.
Steps to reproduce
Create a file with the following spec:
openapi: 3.0.0
info:
title: Sample API
version: '2.0'
paths:
/v2/projects:
post:
operationId: create_project
summary: Create a Project
description: 'To create a project, send a POST request to `/v2/projects`.'
tags:
- Projects
requestBody:
required: true
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/project_base'
required:
- name
- purpose
responses:
'200':
description: OK
components:
schemas:
project_base:
type: object
properties:
id:
type: string
format: uuid
readOnly: true
example: 4e1bfbc3
description: The unique universal identifier of this project.
name:
type: string
maxLength: 175
example: my-web-api
description: >-
The human-readable name for the project. The maximum length is 175
characters and the name must be unique.
description:
type: string
maxLength: 255
example: My website API
description: >-
The description of the project. The maximum length is 255
characters.
purpose:
type: string
maxLength: 255
example: Service or API
run the following:
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate -i/local/projects_allof.yaml -g python -o /local/last-try
Inspect the openapi_client/api/projects_api.py file and see if UNKNOWNBASETYPE is imported and used.
Related issues/PRs
This problem has been described in many issues: #2892 #5903 #7256 #7339. Also not specific to just Python.
openapi-generator version
Openapi 5.0.1, also used the latest master via docker
Issue Analytics
- State:
- Created 3 years ago
- Reactions:13
- Comments:15 (5 by maintainers)
Top GitHub Comments
@stonecharioteer if you have the opportunity use protobuf + gRPC instead.
lol this issue seems to be in literally every single generator… not a very good look for a “spec-compliant” program!