Skip to content

[PYTHON] Fix for failing to lookup discriminator value using AllOf and discriminator #18498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}
# look up the object type based on discriminator mapping
object_type = cls.get_discriminator_value(obj)
{{#mappedModels}}
if object_type == '{{{mappingName}}}':
if object_type == '{{{modelName}}}':
return import_module("{{packageName}}.models.{{model.classVarName}}").{{modelName}}.from_dict(obj)
{{/mappedModels}}
raise ValueError("{{{classname}}} failed to lookup discriminator value from " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}
# look up the object type based on discriminator mapping
object_type = cls.get_discriminator_value(obj)
{{#mappedModels}}
if object_type == '{{{mappingName}}}':
if object_type == '{{{modelName}}}':
return import_module("{{packageName}}.models.{{model.classVarName}}").{{modelName}}.from_dict(obj)
{{/mappedModels}}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2741,3 +2741,26 @@ components:
_name:
type: string
type: object
Info:
allOf:
- $ref: '#/components/schemas/BaseDiscriminator'
- properties:
val:
$ref: '#/components/schemas/BaseDiscriminator'
type: object
BaseDiscriminator:
discriminator:
mapping:
string: '#/components/schemas/PrimitiveString'
propertyName: _typeName
properties:
_typeName:
type: string
type: object
PrimitiveString:
allOf:
- $ref: '#/components/schemas/BaseDiscriminator'
- properties:
_value:
type: string
type: object
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ docs/ArrayOfArrayOfModel.md
docs/ArrayOfArrayOfNumberOnly.md
docs/ArrayOfNumberOnly.md
docs/ArrayTest.md
docs/BaseDiscriminator.md
docs/BasquePig.md
docs/Bathing.md
docs/Capitalization.md
Expand Down Expand Up @@ -53,6 +54,7 @@ docs/FormatTest.md
docs/HasOnlyReadOnly.md
docs/HealthCheckResult.md
docs/ImportTestDatetimeApi.md
docs/Info.md
docs/InnerDictWithProperty.md
docs/InputAllOf.md
docs/IntOrString.md
Expand Down Expand Up @@ -84,6 +86,7 @@ docs/Pet.md
docs/PetApi.md
docs/Pig.md
docs/PoopCleaning.md
docs/PrimitiveString.md
docs/PropertyMap.md
docs/PropertyNameCollision.md
docs/ReadOnlyFirst.md
Expand Down Expand Up @@ -137,6 +140,7 @@ petstore_api/models/array_of_array_of_model.py
petstore_api/models/array_of_array_of_number_only.py
petstore_api/models/array_of_number_only.py
petstore_api/models/array_test.py
petstore_api/models/base_discriminator.py
petstore_api/models/basque_pig.py
petstore_api/models/bathing.py
petstore_api/models/capitalization.py
Expand Down Expand Up @@ -169,6 +173,7 @@ petstore_api/models/foo_get_default_response.py
petstore_api/models/format_test.py
petstore_api/models/has_only_read_only.py
petstore_api/models/health_check_result.py
petstore_api/models/info.py
petstore_api/models/inner_dict_with_property.py
petstore_api/models/input_all_of.py
petstore_api/models/int_or_string.py
Expand Down Expand Up @@ -199,6 +204,7 @@ petstore_api/models/parent_with_optional_dict.py
petstore_api/models/pet.py
petstore_api/models/pig.py
petstore_api/models/poop_cleaning.py
petstore_api/models/primitive_string.py
petstore_api/models/property_map.py
petstore_api/models/property_name_collision.py
petstore_api/models/read_only_first.py
Expand Down
3 changes: 3 additions & 0 deletions samples/openapi3/client/petstore/python-aiohttp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ Class | Method | HTTP request | Description
- [ArrayOfArrayOfNumberOnly](docs/ArrayOfArrayOfNumberOnly.md)
- [ArrayOfNumberOnly](docs/ArrayOfNumberOnly.md)
- [ArrayTest](docs/ArrayTest.md)
- [BaseDiscriminator](docs/BaseDiscriminator.md)
- [BasquePig](docs/BasquePig.md)
- [Bathing](docs/Bathing.md)
- [Capitalization](docs/Capitalization.md)
Expand Down Expand Up @@ -195,6 +196,7 @@ Class | Method | HTTP request | Description
- [FormatTest](docs/FormatTest.md)
- [HasOnlyReadOnly](docs/HasOnlyReadOnly.md)
- [HealthCheckResult](docs/HealthCheckResult.md)
- [Info](docs/Info.md)
- [InnerDictWithProperty](docs/InnerDictWithProperty.md)
- [InputAllOf](docs/InputAllOf.md)
- [IntOrString](docs/IntOrString.md)
Expand Down Expand Up @@ -225,6 +227,7 @@ Class | Method | HTTP request | Description
- [Pet](docs/Pet.md)
- [Pig](docs/Pig.md)
- [PoopCleaning](docs/PoopCleaning.md)
- [PrimitiveString](docs/PrimitiveString.md)
- [PropertyMap](docs/PropertyMap.md)
- [PropertyNameCollision](docs/PropertyNameCollision.md)
- [ReadOnlyFirst](docs/ReadOnlyFirst.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# BaseDiscriminator


## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**type_name** | **str** | | [optional]

## Example

```python
from petstore_api.models.base_discriminator import BaseDiscriminator

# TODO update the JSON string below
json = "{}"
# create an instance of BaseDiscriminator from a JSON string
base_discriminator_instance = BaseDiscriminator.from_json(json)
# print the JSON string representation of the object
print(BaseDiscriminator.to_json())

# convert the object into a dict
base_discriminator_dict = base_discriminator_instance.to_dict()
# create an instance of BaseDiscriminator from a dict
base_discriminator_from_dict = BaseDiscriminator.from_dict(base_discriminator_dict)
```
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)


29 changes: 29 additions & 0 deletions samples/openapi3/client/petstore/python-aiohttp/docs/Info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Info


## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**val** | [**BaseDiscriminator**](BaseDiscriminator.md) | | [optional]

## Example

```python
from petstore_api.models.info import Info

# TODO update the JSON string below
json = "{}"
# create an instance of Info from a JSON string
info_instance = Info.from_json(json)
# print the JSON string representation of the object
print(Info.to_json())

# convert the object into a dict
info_dict = info_instance.to_dict()
# create an instance of Info from a dict
info_from_dict = Info.from_dict(info_dict)
```
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)


Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# PrimitiveString


## Properties

Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**value** | **str** | | [optional]

## Example

```python
from petstore_api.models.primitive_string import PrimitiveString

# TODO update the JSON string below
json = "{}"
# create an instance of PrimitiveString from a JSON string
primitive_string_instance = PrimitiveString.from_json(json)
# print the JSON string representation of the object
print(PrimitiveString.to_json())

# convert the object into a dict
primitive_string_dict = primitive_string_instance.to_dict()
# create an instance of PrimitiveString from a dict
primitive_string_from_dict = PrimitiveString.from_dict(primitive_string_dict)
```
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)


Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
from petstore_api.models.array_of_array_of_number_only import ArrayOfArrayOfNumberOnly
from petstore_api.models.array_of_number_only import ArrayOfNumberOnly
from petstore_api.models.array_test import ArrayTest
from petstore_api.models.base_discriminator import BaseDiscriminator
from petstore_api.models.basque_pig import BasquePig
from petstore_api.models.bathing import Bathing
from petstore_api.models.capitalization import Capitalization
Expand Down Expand Up @@ -84,6 +85,7 @@
from petstore_api.models.format_test import FormatTest
from petstore_api.models.has_only_read_only import HasOnlyReadOnly
from petstore_api.models.health_check_result import HealthCheckResult
from petstore_api.models.info import Info
from petstore_api.models.inner_dict_with_property import InnerDictWithProperty
from petstore_api.models.input_all_of import InputAllOf
from petstore_api.models.int_or_string import IntOrString
Expand Down Expand Up @@ -114,6 +116,7 @@
from petstore_api.models.pet import Pet
from petstore_api.models.pig import Pig
from petstore_api.models.poop_cleaning import PoopCleaning
from petstore_api.models.primitive_string import PrimitiveString
from petstore_api.models.property_map import PropertyMap
from petstore_api.models.property_name_collision import PropertyNameCollision
from petstore_api.models.read_only_first import ReadOnlyFirst
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from petstore_api.models.array_of_array_of_number_only import ArrayOfArrayOfNumberOnly
from petstore_api.models.array_of_number_only import ArrayOfNumberOnly
from petstore_api.models.array_test import ArrayTest
from petstore_api.models.base_discriminator import BaseDiscriminator
from petstore_api.models.basque_pig import BasquePig
from petstore_api.models.bathing import Bathing
from petstore_api.models.capitalization import Capitalization
Expand Down Expand Up @@ -59,6 +60,7 @@
from petstore_api.models.format_test import FormatTest
from petstore_api.models.has_only_read_only import HasOnlyReadOnly
from petstore_api.models.health_check_result import HealthCheckResult
from petstore_api.models.info import Info
from petstore_api.models.inner_dict_with_property import InnerDictWithProperty
from petstore_api.models.input_all_of import InputAllOf
from petstore_api.models.int_or_string import IntOrString
Expand Down Expand Up @@ -89,6 +91,7 @@
from petstore_api.models.pet import Pet
from petstore_api.models.pig import Pig
from petstore_api.models.poop_cleaning import PoopCleaning
from petstore_api.models.primitive_string import PrimitiveString
from petstore_api.models.property_map import PropertyMap
from petstore_api.models.property_name_collision import PropertyNameCollision
from petstore_api.models.read_only_first import ReadOnlyFirst
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# coding: utf-8

"""
OpenAPI Petstore

This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\

The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)

Do not edit the class manually.
""" # noqa: E501


from __future__ import annotations
import pprint
import re # noqa: F401
import json

from importlib import import_module
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing import Optional, Set
from typing_extensions import Self

from typing import TYPE_CHECKING
if TYPE_CHECKING:
from petstore_api.models.primitive_string import PrimitiveString
from petstore_api.models.info import Info

class BaseDiscriminator(BaseModel):
"""
BaseDiscriminator
""" # noqa: E501
type_name: Optional[StrictStr] = Field(default=None, alias="_typeName")
__properties: ClassVar[List[str]] = ["_typeName"]

model_config = ConfigDict(
populate_by_name=True,
validate_assignment=True,
protected_namespaces=(),
)


# JSON field name that stores the object type
__discriminator_property_name: ClassVar[str] = '_typeName'

# discriminator mappings
__discriminator_value_class_map: ClassVar[Dict[str, str]] = {
'string': 'PrimitiveString','Info': 'Info'
}

@classmethod
def get_discriminator_value(cls, obj: Dict[str, Any]) -> Optional[str]:
"""Returns the discriminator value (object type) of the data"""
discriminator_value = obj[cls.__discriminator_property_name]
if discriminator_value:
return cls.__discriminator_value_class_map.get(discriminator_value)
else:
return None

def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))

def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())

@classmethod
def from_json(cls, json_str: str) -> Optional[Union[PrimitiveString, Info]]:
"""Create an instance of BaseDiscriminator from a JSON string"""
return cls.from_dict(json.loads(json_str))

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: Dict[str, Any]) -> Optional[Union[PrimitiveString, Info]]:
"""Create an instance of BaseDiscriminator from a dict"""
# look up the object type based on discriminator mapping
object_type = cls.get_discriminator_value(obj)
if object_type == 'PrimitiveString':
return import_module("petstore_api.models.primitive_string").PrimitiveString.from_dict(obj)
if object_type == 'Info':
return import_module("petstore_api.models.info").Info.from_dict(obj)

raise ValueError("BaseDiscriminator failed to lookup discriminator value from " +
json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name +
", mapping: " + json.dumps(cls.__discriminator_value_class_map))


Loading