Fixes object serialization when there is an inline array property which contains a refed enum (#8387)

* Fixes object inline enum defintion with refed enum item

* Adds refed array model example w/ serialization + deserialization
This commit is contained in:
Justin Black 2021-01-08 13:15:55 -08:00 committed by GitHub
parent f2671fcb78
commit ce893a84ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 355 additions and 21 deletions

View File

@ -1211,10 +1211,13 @@ def model_to_dict(model_instance, serialize=True):
# exist in attribute_map
attr = model_instance.attribute_map.get(attr, attr)
if isinstance(value, list):
result[attr] = list(map(
lambda x: model_to_dict(x, serialize=serialize)
if hasattr(x, '_data_store') else x, value
))
if not value or isinstance(value[0], PRIMITIVE_TYPES):
# empty list or primitive types
result[attr] = value
elif isinstance(value[0], ModelSimple):
result[attr] = [x.value for x in value]
else:
result[attr] = [model_to_dict(x, serialize=serialize) for x in value]
elif isinstance(value, dict):
result[attr] = dict(map(
lambda item: (item[0],

View File

@ -18,7 +18,6 @@
package org.openapitools.codegen.python;
import com.google.common.collect.Sets;
import com.sun.org.apache.xpath.internal.operations.Bool;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.*;

View File

@ -1008,6 +1008,26 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ArrayOfEnums'
/fake/refs/enum-test:
post:
tags:
- fake
summary: Object contains enum properties and array properties containing enums
operationId: EnumTest
requestBody:
description: Input object
content:
application/json:
schema:
$ref: '#/components/schemas/Enum_Test'
required: false
responses:
200:
description: Got object containing enums
content:
application/json:
schema:
$ref: '#/components/schemas/Enum_Test'
/fake/additional-properties-with-array-of-enums:
get:
tags:
@ -1671,6 +1691,12 @@ components:
$ref: '#/components/schemas/IntegerEnumWithDefaultValue'
IntegerEnumOneValue:
$ref: '#/components/schemas/IntegerEnumOneValue'
InlineArrayOfStrEnum:
type: array
items:
$ref: '#/components/schemas/StringEnum'
ArrayOfStrEnum:
$ref: '#/components/schemas/ArrayOfEnums'
AdditionalPropertiesClass:
type: object
properties:

View File

@ -1493,10 +1493,13 @@ def model_to_dict(model_instance, serialize=True):
# exist in attribute_map
attr = model_instance.attribute_map.get(attr, attr)
if isinstance(value, list):
result[attr] = list(map(
lambda x: model_to_dict(x, serialize=serialize)
if hasattr(x, '_data_store') else x, value
))
if not value or isinstance(value[0], PRIMITIVE_TYPES):
# empty list or primitive types
result[attr] = value
elif isinstance(value[0], ModelSimple):
result[attr] = [x.value for x in value]
else:
result[attr] = [model_to_dict(x, serialize=serialize) for x in value]
elif isinstance(value, dict):
result[attr] = dict(map(
lambda item: (item[0],

View File

@ -1493,10 +1493,13 @@ def model_to_dict(model_instance, serialize=True):
# exist in attribute_map
attr = model_instance.attribute_map.get(attr, attr)
if isinstance(value, list):
result[attr] = list(map(
lambda x: model_to_dict(x, serialize=serialize)
if hasattr(x, '_data_store') else x, value
))
if not value or isinstance(value[0], PRIMITIVE_TYPES):
# empty list or primitive types
result[attr] = value
elif isinstance(value[0], ModelSimple):
result[attr] = [x.value for x in value]
else:
result[attr] = [model_to_dict(x, serialize=serialize) for x in value]
elif isinstance(value, dict):
result[attr] = dict(map(
lambda item: (item[0],

View File

@ -1493,10 +1493,13 @@ def model_to_dict(model_instance, serialize=True):
# exist in attribute_map
attr = model_instance.attribute_map.get(attr, attr)
if isinstance(value, list):
result[attr] = list(map(
lambda x: model_to_dict(x, serialize=serialize)
if hasattr(x, '_data_store') else x, value
))
if not value or isinstance(value[0], PRIMITIVE_TYPES):
# empty list or primitive types
result[attr] = value
elif isinstance(value[0], ModelSimple):
result[attr] = [x.value for x in value]
else:
result[attr] = [model_to_dict(x, serialize=serialize) for x in value]
elif isinstance(value, dict):
result[attr] = dict(map(
lambda item: (item[0],

View File

@ -88,6 +88,7 @@ Class | Method | HTTP request | Description
*FakeApi* | [**array_of_enums**](docs/FakeApi.md#array_of_enums) | **POST** /fake/refs/array-of-enums | Array of Enums
*FakeApi* | [**boolean**](docs/FakeApi.md#boolean) | **POST** /fake/refs/boolean |
*FakeApi* | [**composed_one_of_number_with_validations**](docs/FakeApi.md#composed_one_of_number_with_validations) | **POST** /fake/refs/composed_one_of_number_with_validations |
*FakeApi* | [**enum_test**](docs/FakeApi.md#enum_test) | **POST** /fake/refs/enum-test | Object contains enum properties and array properties containing enums
*FakeApi* | [**fake_health_get**](docs/FakeApi.md#fake_health_get) | **GET** /fake/health | Health check endpoint
*FakeApi* | [**mammal**](docs/FakeApi.md#mammal) | **POST** /fake/refs/mammal |
*FakeApi* | [**number_with_validations**](docs/FakeApi.md#number_with_validations) | **POST** /fake/refs/number |

View File

@ -12,6 +12,8 @@ Name | Type | Description | Notes
**string_enum_with_default_value** | [**StringEnumWithDefaultValue**](StringEnumWithDefaultValue.md) | | [optional]
**integer_enum_with_default_value** | [**IntegerEnumWithDefaultValue**](IntegerEnumWithDefaultValue.md) | | [optional]
**integer_enum_one_value** | [**IntegerEnumOneValue**](IntegerEnumOneValue.md) | | [optional]
**inline_array_of_str_enum** | [**[StringEnum]**](StringEnum.md) | | [optional]
**array_of_str_enum** | [**ArrayOfEnums**](ArrayOfEnums.md) | | [optional]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -9,6 +9,7 @@ Method | HTTP request | Description
[**array_of_enums**](FakeApi.md#array_of_enums) | **POST** /fake/refs/array-of-enums | Array of Enums
[**boolean**](FakeApi.md#boolean) | **POST** /fake/refs/boolean |
[**composed_one_of_number_with_validations**](FakeApi.md#composed_one_of_number_with_validations) | **POST** /fake/refs/composed_one_of_number_with_validations |
[**enum_test**](FakeApi.md#enum_test) | **POST** /fake/refs/enum-test | Object contains enum properties and array properties containing enums
[**fake_health_get**](FakeApi.md#fake_health_get) | **GET** /fake/health | Health check endpoint
[**mammal**](FakeApi.md#mammal) | **POST** /fake/refs/mammal |
[**number_with_validations**](FakeApi.md#number_with_validations) | **POST** /fake/refs/number |
@ -346,6 +347,84 @@ No authorization required
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **enum_test**
> EnumTest enum_test()
Object contains enum properties and array properties containing enums
### Example
```python
import time
import petstore_api
from petstore_api.api import fake_api
from petstore_api.model.enum_test import EnumTest
from pprint import pprint
# Defining the host is optional and defaults to http://petstore.swagger.io:80/v2
# See configuration.py for a list of all supported configuration parameters.
configuration = petstore_api.Configuration(
host = "http://petstore.swagger.io:80/v2"
)
# Enter a context with an instance of the API client
with petstore_api.ApiClient() as api_client:
# Create an instance of the API class
api_instance = fake_api.FakeApi(api_client)
enum_test = EnumTest(
enum_string="UPPER",
enum_string_required="UPPER",
enum_integer=1,
enum_number=1.1,
string_enum=StringEnum("placed"),
integer_enum=IntegerEnum(0),
string_enum_with_default_value=StringEnumWithDefaultValue("placed"),
integer_enum_with_default_value=IntegerEnumWithDefaultValue(0),
integer_enum_one_value=IntegerEnumOneValue(0),
inline_array_of_str_enum=[
StringEnum("placed"),
],
array_of_str_enum=ArrayOfEnums([
StringEnum("placed"),
]),
) # EnumTest | Input object (optional)
# example passing only required values which don't have defaults set
# and optional values
try:
# Object contains enum properties and array properties containing enums
api_response = api_instance.enum_test(enum_test=enum_test)
pprint(api_response)
except petstore_api.ApiException as e:
print("Exception when calling FakeApi->enum_test: %s\n" % e)
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**enum_test** | [**EnumTest**](EnumTest.md)| Input object | [optional]
### Return type
[**EnumTest**](EnumTest.md)
### Authorization
No authorization required
### HTTP request headers
- **Content-Type**: application/json
- **Accept**: application/json
### HTTP response details
| Status code | Description | Response headers |
|-------------|-------------|------------------|
**200** | Got object containing enums | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **fake_health_get**
> HealthCheckResult fake_health_get()

View File

@ -26,6 +26,7 @@ from petstore_api.model.animal_farm import AnimalFarm
from petstore_api.model.array_of_enums import ArrayOfEnums
from petstore_api.model.client import Client
from petstore_api.model.composed_one_of_number_with_validations import ComposedOneOfNumberWithValidations
from petstore_api.model.enum_test import EnumTest
from petstore_api.model.file_schema_test_class import FileSchemaTestClass
from petstore_api.model.health_check_result import HealthCheckResult
from petstore_api.model.mammal import Mammal
@ -605,6 +606,117 @@ class FakeApi(object):
callable=__composed_one_of_number_with_validations
)
def __enum_test(
self,
**kwargs
):
"""Object contains enum properties and array properties containing enums # noqa: E501
This method makes a synchronous HTTP request by default. To make an
asynchronous HTTP request, please pass async_req=True
>>> thread = api.enum_test(async_req=True)
>>> result = thread.get()
Keyword Args:
enum_test (EnumTest): Input object. [optional]
_return_http_data_only (bool): response data without head status
code and headers. Default is True.
_preload_content (bool): if False, the urllib3.HTTPResponse object
will be returned without reading/decoding response data.
Default is True.
_request_timeout (float/tuple): timeout setting for this request. If one
number provided, it will be total request timeout. It can also
be a pair (tuple) of (connection, read) timeouts.
Default is None.
_check_input_type (bool): specifies if type checking
should be done one the data sent to the server.
Default is True.
_check_return_type (bool): specifies if type checking
should be done one the data received from the server.
Default is True.
_host_index (int/None): specifies the index of the server
that we want to use.
Default is read from the configuration.
async_req (bool): execute request asynchronously
Returns:
EnumTest
If the method is called asynchronously, returns the request
thread.
"""
kwargs['async_req'] = kwargs.get(
'async_req', False
)
kwargs['_return_http_data_only'] = kwargs.get(
'_return_http_data_only', True
)
kwargs['_preload_content'] = kwargs.get(
'_preload_content', True
)
kwargs['_request_timeout'] = kwargs.get(
'_request_timeout', None
)
kwargs['_check_input_type'] = kwargs.get(
'_check_input_type', True
)
kwargs['_check_return_type'] = kwargs.get(
'_check_return_type', True
)
kwargs['_host_index'] = kwargs.get('_host_index')
return self.call_with_http_info(**kwargs)
self.enum_test = Endpoint(
settings={
'response_type': (EnumTest,),
'auth': [],
'endpoint_path': '/fake/refs/enum-test',
'operation_id': 'enum_test',
'http_method': 'POST',
'servers': None,
},
params_map={
'all': [
'enum_test',
],
'required': [],
'nullable': [
],
'enum': [
],
'validation': [
]
},
root_map={
'validations': {
},
'allowed_values': {
},
'openapi_types': {
'enum_test':
(EnumTest,),
},
'attribute_map': {
},
'location_map': {
'enum_test': 'body',
},
'collection_format_map': {
}
},
headers_map={
'accept': [
'application/json'
],
'content_type': [
'application/json'
]
},
api_client=api_client,
callable=__enum_test
)
def __fake_health_get(
self,
**kwargs

View File

@ -29,11 +29,13 @@ from petstore_api.model_utils import ( # noqa: F401
)
def lazy_import():
from petstore_api.model.array_of_enums import ArrayOfEnums
from petstore_api.model.integer_enum import IntegerEnum
from petstore_api.model.integer_enum_one_value import IntegerEnumOneValue
from petstore_api.model.integer_enum_with_default_value import IntegerEnumWithDefaultValue
from petstore_api.model.string_enum import StringEnum
from petstore_api.model.string_enum_with_default_value import StringEnumWithDefaultValue
globals()['ArrayOfEnums'] = ArrayOfEnums
globals()['IntegerEnum'] = IntegerEnum
globals()['IntegerEnumOneValue'] = IntegerEnumOneValue
globals()['IntegerEnumWithDefaultValue'] = IntegerEnumWithDefaultValue
@ -114,6 +116,8 @@ class EnumTest(ModelNormal):
'string_enum_with_default_value': (StringEnumWithDefaultValue,), # noqa: E501
'integer_enum_with_default_value': (IntegerEnumWithDefaultValue,), # noqa: E501
'integer_enum_one_value': (IntegerEnumOneValue,), # noqa: E501
'inline_array_of_str_enum': ([StringEnum],), # noqa: E501
'array_of_str_enum': (ArrayOfEnums,), # noqa: E501
}
@cached_property
@ -131,6 +135,8 @@ class EnumTest(ModelNormal):
'string_enum_with_default_value': 'StringEnumWithDefaultValue', # noqa: E501
'integer_enum_with_default_value': 'IntegerEnumWithDefaultValue', # noqa: E501
'integer_enum_one_value': 'IntegerEnumOneValue', # noqa: E501
'inline_array_of_str_enum': 'InlineArrayOfStrEnum', # noqa: E501
'array_of_str_enum': 'ArrayOfStrEnum', # noqa: E501
}
_composed_schemas = {}
@ -190,6 +196,8 @@ class EnumTest(ModelNormal):
string_enum_with_default_value (StringEnumWithDefaultValue): [optional] # noqa: E501
integer_enum_with_default_value (IntegerEnumWithDefaultValue): [optional] # noqa: E501
integer_enum_one_value (IntegerEnumOneValue): [optional] # noqa: E501
inline_array_of_str_enum ([StringEnum]): [optional] # noqa: E501
array_of_str_enum (ArrayOfEnums): [optional] # noqa: E501
"""
_check_type = kwargs.pop('_check_type', True)

View File

@ -1493,10 +1493,13 @@ def model_to_dict(model_instance, serialize=True):
# exist in attribute_map
attr = model_instance.attribute_map.get(attr, attr)
if isinstance(value, list):
result[attr] = list(map(
lambda x: model_to_dict(x, serialize=serialize)
if hasattr(x, '_data_store') else x, value
))
if not value or isinstance(value[0], PRIMITIVE_TYPES):
# empty list or primitive types
result[attr] = value
elif isinstance(value[0], ModelSimple):
result[attr] = [x.value for x in value]
else:
result[attr] = [model_to_dict(x, serialize=serialize) for x in value]
elif isinstance(value, dict):
result[attr] = dict(map(
lambda item: (item[0],

View File

@ -0,0 +1,46 @@
# 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: \" \\ # noqa: E501
The version of the OpenAPI document: 1.0.0
Generated by: https://openapi-generator.tech
"""
import sys
import unittest
import petstore_api
from petstore_api.model.enum_test import EnumTest
from petstore_api.model.string_enum import StringEnum
from petstore_api.model.array_of_enums import ArrayOfEnums
class TestEnumTest(unittest.TestCase):
"""EnumTest unit test stubs"""
def setUp(self):
pass
def tearDown(self):
pass
def testEnumTest(self):
"""Test EnumTest"""
# inline array of enums
model = EnumTest(
enum_string_required='lower',
inline_array_of_str_enum=[StringEnum('approved')]
)
# refed array of enums
model = EnumTest(
enum_string_required='lower',
array_of_str_enum=ArrayOfEnums([StringEnum('approved')])
)
if __name__ == '__main__':
unittest.main()

View File

@ -119,6 +119,52 @@ class TestFakeApi(unittest.TestCase):
"""
pass
def test_enum_test(self):
"""Test case for enum_test
Object contains enum properties and array properties containing enums
"""
from petstore_api.model.enum_test import EnumTest
from petstore_api.model.string_enum import StringEnum
from petstore_api.model.array_of_enums import ArrayOfEnums
endpoint = self.api.enum_test
assert endpoint.openapi_types['enum_test'] == (EnumTest,)
assert endpoint.settings['response_type'] == (EnumTest,)
# serialization + deserialization works w/ inline array
with patch.object(RESTClientObject, 'request') as mock_method:
body = EnumTest(
enum_string_required='lower',
inline_array_of_str_enum=[StringEnum('approved')]
)
json_value = {'enum_string_required': 'lower', 'InlineArrayOfStrEnum': ['approved']}
mock_method.return_value = self.mock_response(json_value)
response = endpoint(enum_test=body)
self.assert_request_called_with(
mock_method, 'http://petstore.swagger.io:80/v2/fake/refs/enum-test', json_value)
assert isinstance(response, EnumTest)
assert response == body
# serialization + deserialization works w/ refed array
with patch.object(RESTClientObject, 'request') as mock_method:
body = EnumTest(
enum_string_required='lower',
array_of_str_enum=ArrayOfEnums([StringEnum('approved')])
)
json_value = {'enum_string_required': 'lower', 'ArrayOfStrEnum': ['approved']}
mock_method.return_value = self.mock_response(json_value)
response = endpoint(enum_test=body)
self.assert_request_called_with(
mock_method, 'http://petstore.swagger.io:80/v2/fake/refs/enum-test', json_value)
assert isinstance(response, EnumTest)
assert response == body
def test_array_of_enums(self):
"""Test case for array_of_enums