[PYTHON]: Bug or not bug ? Using allOf for inheritance generate bad imports
Hi, I'm not sure what i will describe is a bug; I prefer to give you some clues and have a little chat before openning a bug.
Context: I fetch a swagger generated from one of my colleagues who is using Swashbuckle and the inheritance for the Dog schema use the following syntax:
openapi: 3.0.1
info:
title: title
version: 1.0.0
paths: {}
components:
schemas:
Dog:
type: object
allOf:
- $ref: '#/components/schemas/Animal'
properties:
food_eaten:
type: array
items:
oneOf:
- $ref: '#/components/schemas/Treat'
Animal:
type: object
Treat:
type: object
When generate python flask server, the imports are kinda broken.
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli:v7.6.0 generate -i /local/test.yaml -g python-flask -o /local/dist
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from openapi_server.models.base_model import Model
from openapi_server.models.one_ofobject import OneOfobject
from openapi_server import util
from openapi_server.models.one_ofobject import OneOfobject # noqa: E501
class Dog(Model):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
"""
def __init__(self, food_eaten=None): # noqa: E501
"""Dog - a model defined in OpenAPI
:param food_eaten: The food_eaten of this Dog. # noqa: E501
:type food_eaten: List[OneOfobject]
"""
self.openapi_types = {
'food_eaten': List[OneOfobject]
}
self.attribute_map = {
'food_eaten': 'food_eaten'
}
self._food_eaten = food_eaten
@classmethod
def from_dict(cls, dikt) -> 'Dog':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The Dog of this Dog. # noqa: E501
:rtype: Dog
"""
return util.deserialize_model(dikt, cls)
@property
def food_eaten(self) -> List[OneOfobject]:
"""Gets the food_eaten of this Dog.
:return: The food_eaten of this Dog.
:rtype: List[OneOfobject]
"""
return self._food_eaten
@food_eaten.setter
def food_eaten(self, food_eaten: List[OneOfobject]):
"""Sets the food_eaten of this Dog.
:param food_eaten: The food_eaten of this Dog.
:type food_eaten: List[OneOfobject]
"""
self._food_eaten = food_eaten
I saw on swagger.io that the syntax of allOf should be the following one:
openapi: 3.0.1
info:
title: title
version: 1.0.0
paths: {}
components:
schemas:
Dog:
type: object
allOf:
- $ref: '#/components/schemas/Animal'
- type: object
properties:
food_eaten:
type: array
items:
oneOf:
- $ref: '#/components/schemas/Treat'
Animal:
type: object
Treat:
type: object
When i'm using this one, the imports are correct (working):
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from openapi_server.models.base_model import Model
from openapi_server.models.dog_all_of_food_eaten import DogAllOfFoodEaten
from openapi_server import util
from openapi_server.models.dog_all_of_food_eaten import DogAllOfFoodEaten # noqa: E501
class Dog(Model):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
"""
def __init__(self, food_eaten=None): # noqa: E501
"""Dog - a model defined in OpenAPI
:param food_eaten: The food_eaten of this Dog. # noqa: E501
:type food_eaten: List[DogAllOfFoodEaten]
"""
self.openapi_types = {
'food_eaten': List[DogAllOfFoodEaten]
}
self.attribute_map = {
'food_eaten': 'food_eaten'
}
self._food_eaten = food_eaten
@classmethod
def from_dict(cls, dikt) -> 'Dog':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The Dog of this Dog. # noqa: E501
:rtype: Dog
"""
return util.deserialize_model(dikt, cls)
@property
def food_eaten(self) -> List[DogAllOfFoodEaten]:
"""Gets the food_eaten of this Dog.
:return: The food_eaten of this Dog.
:rtype: List[DogAllOfFoodEaten]
"""
return self._food_eaten
@food_eaten.setter
def food_eaten(self, food_eaten: List[DogAllOfFoodEaten]):
"""Sets the food_eaten of this Dog.
:param food_eaten: The food_eaten of this Dog.
:type food_eaten: List[DogAllOfFoodEaten]
"""
self._food_eaten = food_eaten
- Why the first syntax break the imports ? Is the syntax wrong ?
- When im using the second syntax, i dont understand why it is generating a
DogAllOfFoodEaten.
Actual:
self.openapi_types = {
'food_eaten': List[DogAllOfFoodEaten]
}
Expected:
self.openapi_types = {
'food_eaten': List[Treat | DogBiscuit | SomethingElse]
}
Thanks for all you have done so far. I really appreciate it. Have a good day.
https://github.com/openapitools/openapi-generator/blob/master/docs/customization.md#openapi-normalizer
can you please enabled the normalizer rule REFACTOR_ALLOF_WITH_PROPERTIES_ONLY?
oneOf: - $ref: '#/components/schemas/Treat'
this is an inline schema so it will be created as a model separately
Thanks @wing328 for your help, it works !
Could you please indicate me if it is a normal behavior ?
- When im using the second syntax, i dont understand why it is generating a
DogAllOfFoodEaten.Actual:
self.openapi_types = { 'food_eaten': List[DogAllOfFoodEaten] }Expected:
self.openapi_types = { 'food_eaten': List[Treat | DogBiscuit | SomethingElse] }
Thanks !