From 6bcc28d06e990dede3c71d3e147be86ea4fe455b Mon Sep 17 00:00:00 2001 From: BaptisteSaves <119934226+BaptisteSaves@users.noreply.github.com> Date: Wed, 10 Apr 2024 15:12:37 +0200 Subject: [PATCH] Python: Correctly serialize enum with its value (#18327) (#18328) --- .../main/resources/python/api_client.mustache | 2 + ...ith-fake-endpoints-models-for-testing.yaml | 7 ++++ .../openapi_client/api_client.py | 2 + .../python/openapi_client/api_client.py | 2 + .../petstore/python-aiohttp/docs/FakeApi.md | 7 +++- .../petstore_api/api/fake_api.py | 19 ++++++++++ .../python-aiohttp/petstore_api/api_client.py | 2 + .../docs/FakeApi.md | 7 +++- .../petstore_api/api/fake_api.py | 18 +++++++-- .../python-pydantic-v1/docs/FakeApi.md | 7 +++- .../petstore_api/api/fake_api.py | 22 ++++++++--- .../petstore/python/docs/EnumSerialization.md | 11 ++++++ .../client/petstore/python/docs/FakeApi.md | 7 +++- .../python/petstore_api/api/fake_api.py | 19 ++++++++++ .../python/petstore_api/api_client.py | 2 + .../petstore_api/models/enum_serialization.py | 37 +++++++++++++++++++ .../python/test/test_enum_serialization.py | 33 +++++++++++++++++ .../petstore/python/tests/test_api_client.py | 34 +++++++++++------ .../petstore/python/tests/test_fake_api.py | 25 ++++++++++++- 19 files changed, 233 insertions(+), 30 deletions(-) create mode 100644 samples/openapi3/client/petstore/python/docs/EnumSerialization.md create mode 100644 samples/openapi3/client/petstore/python/petstore_api/models/enum_serialization.py create mode 100644 samples/openapi3/client/petstore/python/test/test_enum_serialization.py diff --git a/modules/openapi-generator/src/main/resources/python/api_client.mustache b/modules/openapi-generator/src/main/resources/python/api_client.mustache index 67395798dde6..97b8f8d84c72 100644 --- a/modules/openapi-generator/src/main/resources/python/api_client.mustache +++ b/modules/openapi-generator/src/main/resources/python/api_client.mustache @@ -358,6 +358,8 @@ class ApiClient: """ if obj is None: return None + elif isinstance(obj, Enum): + return obj.value elif isinstance(obj, SecretStr): return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): diff --git a/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml b/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml index 2fc18c1d6447..0d98d5759736 100644 --- a/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml @@ -894,6 +894,13 @@ paths: '*/*': schema: $ref: '#/components/schemas/OuterObjectWithEnumProperty' + parameters: + - in: query + name: param + schema: + type: array + items: + $ref: '#/components/schemas/OuterEnumInteger' requestBody: required: true content: diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api_client.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api_client.py index b03fdf002669..5e39f780d88a 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api_client.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api_client.py @@ -351,6 +351,8 @@ def sanitize_for_serialization(self, obj): """ if obj is None: return None + elif isinstance(obj, Enum): + return obj.value elif isinstance(obj, SecretStr): return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): diff --git a/samples/client/echo_api/python/openapi_client/api_client.py b/samples/client/echo_api/python/openapi_client/api_client.py index b03fdf002669..5e39f780d88a 100644 --- a/samples/client/echo_api/python/openapi_client/api_client.py +++ b/samples/client/echo_api/python/openapi_client/api_client.py @@ -351,6 +351,8 @@ def sanitize_for_serialization(self, obj): """ if obj is None: return None + elif isinstance(obj, Enum): + return obj.value elif isinstance(obj, SecretStr): return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): diff --git a/samples/openapi3/client/petstore/python-aiohttp/docs/FakeApi.md b/samples/openapi3/client/petstore/python-aiohttp/docs/FakeApi.md index 83d1c1d37d4c..a04e01c3df64 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/docs/FakeApi.md +++ b/samples/openapi3/client/petstore/python-aiohttp/docs/FakeApi.md @@ -632,7 +632,7 @@ 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) # **fake_property_enum_integer_serialize** -> OuterObjectWithEnumProperty fake_property_enum_integer_serialize(outer_object_with_enum_property) +> OuterObjectWithEnumProperty fake_property_enum_integer_serialize(outer_object_with_enum_property, param=param) @@ -643,6 +643,7 @@ Test serialization of enum (int) properties with examples ```python import petstore_api +from petstore_api.models.outer_enum_integer import OuterEnumInteger from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty from petstore_api.rest import ApiException from pprint import pprint @@ -659,9 +660,10 @@ async with petstore_api.ApiClient(configuration) as api_client: # Create an instance of the API class api_instance = petstore_api.FakeApi(api_client) outer_object_with_enum_property = petstore_api.OuterObjectWithEnumProperty() # OuterObjectWithEnumProperty | Input enum (int) as post body + param = [petstore_api.OuterEnumInteger()] # List[OuterEnumInteger] | (optional) try: - api_response = await api_instance.fake_property_enum_integer_serialize(outer_object_with_enum_property) + api_response = await api_instance.fake_property_enum_integer_serialize(outer_object_with_enum_property, param=param) print("The response of FakeApi->fake_property_enum_integer_serialize:\n") pprint(api_response) except Exception as e: @@ -676,6 +678,7 @@ async with petstore_api.ApiClient(configuration) as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **outer_object_with_enum_property** | [**OuterObjectWithEnumProperty**](OuterObjectWithEnumProperty.md)| Input enum (int) as post body | + **param** | [**List[OuterEnumInteger]**](OuterEnumInteger.md)| | [optional] ### Return type diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py index dc839324d4cb..078561dd4075 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py @@ -25,6 +25,7 @@ from petstore_api.models.file_schema_test_class import FileSchemaTestClass from petstore_api.models.health_check_result import HealthCheckResult from petstore_api.models.outer_composite import OuterComposite +from petstore_api.models.outer_enum_integer import OuterEnumInteger from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty from petstore_api.models.pet import Pet from petstore_api.models.tag import Tag @@ -2179,6 +2180,7 @@ def _fake_outer_string_serialize_serialize( async def fake_property_enum_integer_serialize( self, outer_object_with_enum_property: Annotated[OuterObjectWithEnumProperty, Field(description="Input enum (int) as post body")], + param: Optional[List[OuterEnumInteger]] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -2198,6 +2200,8 @@ async def fake_property_enum_integer_serialize( :param outer_object_with_enum_property: Input enum (int) as post body (required) :type outer_object_with_enum_property: OuterObjectWithEnumProperty + :param param: + :type param: List[OuterEnumInteger] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -2222,6 +2226,7 @@ async def fake_property_enum_integer_serialize( _param = self._fake_property_enum_integer_serialize_serialize( outer_object_with_enum_property=outer_object_with_enum_property, + param=param, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -2246,6 +2251,7 @@ async def fake_property_enum_integer_serialize( async def fake_property_enum_integer_serialize_with_http_info( self, outer_object_with_enum_property: Annotated[OuterObjectWithEnumProperty, Field(description="Input enum (int) as post body")], + param: Optional[List[OuterEnumInteger]] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -2265,6 +2271,8 @@ async def fake_property_enum_integer_serialize_with_http_info( :param outer_object_with_enum_property: Input enum (int) as post body (required) :type outer_object_with_enum_property: OuterObjectWithEnumProperty + :param param: + :type param: List[OuterEnumInteger] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -2289,6 +2297,7 @@ async def fake_property_enum_integer_serialize_with_http_info( _param = self._fake_property_enum_integer_serialize_serialize( outer_object_with_enum_property=outer_object_with_enum_property, + param=param, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -2313,6 +2322,7 @@ async def fake_property_enum_integer_serialize_with_http_info( async def fake_property_enum_integer_serialize_without_preload_content( self, outer_object_with_enum_property: Annotated[OuterObjectWithEnumProperty, Field(description="Input enum (int) as post body")], + param: Optional[List[OuterEnumInteger]] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -2332,6 +2342,8 @@ async def fake_property_enum_integer_serialize_without_preload_content( :param outer_object_with_enum_property: Input enum (int) as post body (required) :type outer_object_with_enum_property: OuterObjectWithEnumProperty + :param param: + :type param: List[OuterEnumInteger] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -2356,6 +2368,7 @@ async def fake_property_enum_integer_serialize_without_preload_content( _param = self._fake_property_enum_integer_serialize_serialize( outer_object_with_enum_property=outer_object_with_enum_property, + param=param, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -2375,6 +2388,7 @@ async def fake_property_enum_integer_serialize_without_preload_content( def _fake_property_enum_integer_serialize_serialize( self, outer_object_with_enum_property, + param, _request_auth, _content_type, _headers, @@ -2384,6 +2398,7 @@ def _fake_property_enum_integer_serialize_serialize( _host = None _collection_formats: Dict[str, str] = { + 'param': 'multi', } _path_params: Dict[str, str] = {} @@ -2395,6 +2410,10 @@ def _fake_property_enum_integer_serialize_serialize( # process the path parameters # process the query parameters + if param is not None: + + _query_params.append(('param', param)) + # process the header parameters # process the form parameters # process the body parameter diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api_client.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api_client.py index 0d941bcd0e48..991b0d96cc1d 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api_client.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api_client.py @@ -353,6 +353,8 @@ def sanitize_for_serialization(self, obj): """ if obj is None: return None + elif isinstance(obj, Enum): + return obj.value elif isinstance(obj, SecretStr): return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): diff --git a/samples/openapi3/client/petstore/python-pydantic-v1-aiohttp/docs/FakeApi.md b/samples/openapi3/client/petstore/python-pydantic-v1-aiohttp/docs/FakeApi.md index 22c6daa82b19..e33215808a67 100644 --- a/samples/openapi3/client/petstore/python-pydantic-v1-aiohttp/docs/FakeApi.md +++ b/samples/openapi3/client/petstore/python-pydantic-v1-aiohttp/docs/FakeApi.md @@ -624,7 +624,7 @@ 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) # **fake_property_enum_integer_serialize** -> OuterObjectWithEnumProperty fake_property_enum_integer_serialize(outer_object_with_enum_property) +> OuterObjectWithEnumProperty fake_property_enum_integer_serialize(outer_object_with_enum_property, param=param) @@ -636,6 +636,7 @@ Test serialization of enum (int) properties with examples import time import os import petstore_api +from petstore_api.models.outer_enum_integer import OuterEnumInteger from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty from petstore_api.rest import ApiException from pprint import pprint @@ -652,9 +653,10 @@ async with petstore_api.ApiClient(configuration) as api_client: # Create an instance of the API class api_instance = petstore_api.FakeApi(api_client) outer_object_with_enum_property = petstore_api.OuterObjectWithEnumProperty() # OuterObjectWithEnumProperty | Input enum (int) as post body + param = [petstore_api.OuterEnumInteger()] # List[OuterEnumInteger] | (optional) try: - api_response = await api_instance.fake_property_enum_integer_serialize(outer_object_with_enum_property) + api_response = await api_instance.fake_property_enum_integer_serialize(outer_object_with_enum_property, param=param) print("The response of FakeApi->fake_property_enum_integer_serialize:\n") pprint(api_response) except Exception as e: @@ -668,6 +670,7 @@ async with petstore_api.ApiClient(configuration) as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **outer_object_with_enum_property** | [**OuterObjectWithEnumProperty**](OuterObjectWithEnumProperty.md)| Input enum (int) as post body | + **param** | [**List[OuterEnumInteger]**](OuterEnumInteger.md)| | [optional] ### Return type diff --git a/samples/openapi3/client/petstore/python-pydantic-v1-aiohttp/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-pydantic-v1-aiohttp/petstore_api/api/fake_api.py index da27c4cd9545..ab7bdb1b0d60 100644 --- a/samples/openapi3/client/petstore/python-pydantic-v1-aiohttp/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-pydantic-v1-aiohttp/petstore_api/api/fake_api.py @@ -31,6 +31,7 @@ from petstore_api.models.file_schema_test_class import FileSchemaTestClass from petstore_api.models.health_check_result import HealthCheckResult from petstore_api.models.outer_composite import OuterComposite +from petstore_api.models.outer_enum_integer import OuterEnumInteger from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty from petstore_api.models.pet import Pet from petstore_api.models.tag import Tag @@ -1075,13 +1076,15 @@ async def fake_outer_string_serialize_with_http_info(self, body : Annotated[Opti _request_auth=_params.get('_request_auth')) @validate_arguments - async def fake_property_enum_integer_serialize(self, outer_object_with_enum_property : Annotated[OuterObjectWithEnumProperty, Field(..., description="Input enum (int) as post body")], **kwargs) -> OuterObjectWithEnumProperty: # noqa: E501 + async def fake_property_enum_integer_serialize(self, outer_object_with_enum_property : Annotated[OuterObjectWithEnumProperty, Field(..., description="Input enum (int) as post body")], param : Optional[conlist(OuterEnumInteger)] = None, **kwargs) -> OuterObjectWithEnumProperty: # noqa: E501 """fake_property_enum_integer_serialize # noqa: E501 Test serialization of enum (int) properties with examples # noqa: E501 :param outer_object_with_enum_property: Input enum (int) as post body (required) :type outer_object_with_enum_property: OuterObjectWithEnumProperty + :param param: + :type param: List[OuterEnumInteger] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -1095,16 +1098,18 @@ async def fake_property_enum_integer_serialize(self, outer_object_with_enum_prop if '_preload_content' in kwargs: message = "Error! Please call the fake_property_enum_integer_serialize_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 raise ValueError(message) - return await self.fake_property_enum_integer_serialize_with_http_info(outer_object_with_enum_property, **kwargs) # noqa: E501 + return await self.fake_property_enum_integer_serialize_with_http_info(outer_object_with_enum_property, param, **kwargs) # noqa: E501 @validate_arguments - async def fake_property_enum_integer_serialize_with_http_info(self, outer_object_with_enum_property : Annotated[OuterObjectWithEnumProperty, Field(..., description="Input enum (int) as post body")], **kwargs) -> ApiResponse: # noqa: E501 + async def fake_property_enum_integer_serialize_with_http_info(self, outer_object_with_enum_property : Annotated[OuterObjectWithEnumProperty, Field(..., description="Input enum (int) as post body")], param : Optional[conlist(OuterEnumInteger)] = None, **kwargs) -> ApiResponse: # noqa: E501 """fake_property_enum_integer_serialize # noqa: E501 Test serialization of enum (int) properties with examples # noqa: E501 :param outer_object_with_enum_property: Input enum (int) as post body (required) :type outer_object_with_enum_property: OuterObjectWithEnumProperty + :param param: + :type param: List[OuterEnumInteger] :param _preload_content: if False, the ApiResponse.data will be set to none and raw_data will store the HTTP response body without reading/decoding. @@ -1131,7 +1136,8 @@ async def fake_property_enum_integer_serialize_with_http_info(self, outer_object _params = locals() _all_params = [ - 'outer_object_with_enum_property' + 'outer_object_with_enum_property', + 'param' ] _all_params.extend( [ @@ -1161,6 +1167,10 @@ async def fake_property_enum_integer_serialize_with_http_info(self, outer_object # process the query parameters _query_params = [] + if _params.get('param') is not None: # noqa: E501 + _query_params.append(('param', _params['param'])) + _collection_formats['param'] = 'multi' + # process the header parameters _header_params = dict(_params.get('_headers', {})) # process the form parameters diff --git a/samples/openapi3/client/petstore/python-pydantic-v1/docs/FakeApi.md b/samples/openapi3/client/petstore/python-pydantic-v1/docs/FakeApi.md index a4f0f72b5bd5..59d600df9879 100644 --- a/samples/openapi3/client/petstore/python-pydantic-v1/docs/FakeApi.md +++ b/samples/openapi3/client/petstore/python-pydantic-v1/docs/FakeApi.md @@ -624,7 +624,7 @@ 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) # **fake_property_enum_integer_serialize** -> OuterObjectWithEnumProperty fake_property_enum_integer_serialize(outer_object_with_enum_property) +> OuterObjectWithEnumProperty fake_property_enum_integer_serialize(outer_object_with_enum_property, param=param) @@ -636,6 +636,7 @@ Test serialization of enum (int) properties with examples import time import os import petstore_api +from petstore_api.models.outer_enum_integer import OuterEnumInteger from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty from petstore_api.rest import ApiException from pprint import pprint @@ -652,9 +653,10 @@ with petstore_api.ApiClient(configuration) as api_client: # Create an instance of the API class api_instance = petstore_api.FakeApi(api_client) outer_object_with_enum_property = petstore_api.OuterObjectWithEnumProperty() # OuterObjectWithEnumProperty | Input enum (int) as post body + param = [petstore_api.OuterEnumInteger()] # List[OuterEnumInteger] | (optional) try: - api_response = api_instance.fake_property_enum_integer_serialize(outer_object_with_enum_property) + api_response = api_instance.fake_property_enum_integer_serialize(outer_object_with_enum_property, param=param) print("The response of FakeApi->fake_property_enum_integer_serialize:\n") pprint(api_response) except Exception as e: @@ -668,6 +670,7 @@ with petstore_api.ApiClient(configuration) as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **outer_object_with_enum_property** | [**OuterObjectWithEnumProperty**](OuterObjectWithEnumProperty.md)| Input enum (int) as post body | + **param** | [**List[OuterEnumInteger]**](OuterEnumInteger.md)| | [optional] ### Return type diff --git a/samples/openapi3/client/petstore/python-pydantic-v1/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-pydantic-v1/petstore_api/api/fake_api.py index cc35197590a2..88992b423cc3 100644 --- a/samples/openapi3/client/petstore/python-pydantic-v1/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-pydantic-v1/petstore_api/api/fake_api.py @@ -30,6 +30,7 @@ from petstore_api.models.file_schema_test_class import FileSchemaTestClass from petstore_api.models.health_check_result import HealthCheckResult from petstore_api.models.outer_composite import OuterComposite +from petstore_api.models.outer_enum_integer import OuterEnumInteger from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty from petstore_api.models.pet import Pet from petstore_api.models.tag import Tag @@ -1202,18 +1203,20 @@ def fake_outer_string_serialize_with_http_info(self, body : Annotated[Optional[S _request_auth=_params.get('_request_auth')) @validate_arguments - def fake_property_enum_integer_serialize(self, outer_object_with_enum_property : Annotated[OuterObjectWithEnumProperty, Field(..., description="Input enum (int) as post body")], **kwargs) -> OuterObjectWithEnumProperty: # noqa: E501 + def fake_property_enum_integer_serialize(self, outer_object_with_enum_property : Annotated[OuterObjectWithEnumProperty, Field(..., description="Input enum (int) as post body")], param : Optional[conlist(OuterEnumInteger)] = None, **kwargs) -> OuterObjectWithEnumProperty: # noqa: E501 """fake_property_enum_integer_serialize # noqa: E501 Test serialization of enum (int) properties with examples # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.fake_property_enum_integer_serialize(outer_object_with_enum_property, async_req=True) + >>> thread = api.fake_property_enum_integer_serialize(outer_object_with_enum_property, param, async_req=True) >>> result = thread.get() :param outer_object_with_enum_property: Input enum (int) as post body (required) :type outer_object_with_enum_property: OuterObjectWithEnumProperty + :param param: + :type param: List[OuterEnumInteger] :param async_req: Whether to execute the request asynchronously. :type async_req: bool, optional :param _request_timeout: timeout setting for this request. @@ -1229,21 +1232,23 @@ def fake_property_enum_integer_serialize(self, outer_object_with_enum_property : if '_preload_content' in kwargs: message = "Error! Please call the fake_property_enum_integer_serialize_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501 raise ValueError(message) - return self.fake_property_enum_integer_serialize_with_http_info(outer_object_with_enum_property, **kwargs) # noqa: E501 + return self.fake_property_enum_integer_serialize_with_http_info(outer_object_with_enum_property, param, **kwargs) # noqa: E501 @validate_arguments - def fake_property_enum_integer_serialize_with_http_info(self, outer_object_with_enum_property : Annotated[OuterObjectWithEnumProperty, Field(..., description="Input enum (int) as post body")], **kwargs) -> ApiResponse: # noqa: E501 + def fake_property_enum_integer_serialize_with_http_info(self, outer_object_with_enum_property : Annotated[OuterObjectWithEnumProperty, Field(..., description="Input enum (int) as post body")], param : Optional[conlist(OuterEnumInteger)] = None, **kwargs) -> ApiResponse: # noqa: E501 """fake_property_enum_integer_serialize # noqa: E501 Test serialization of enum (int) properties with examples # noqa: E501 This method makes a synchronous HTTP request by default. To make an asynchronous HTTP request, please pass async_req=True - >>> thread = api.fake_property_enum_integer_serialize_with_http_info(outer_object_with_enum_property, async_req=True) + >>> thread = api.fake_property_enum_integer_serialize_with_http_info(outer_object_with_enum_property, param, async_req=True) >>> result = thread.get() :param outer_object_with_enum_property: Input enum (int) as post body (required) :type outer_object_with_enum_property: OuterObjectWithEnumProperty + :param param: + :type param: List[OuterEnumInteger] :param async_req: Whether to execute the request asynchronously. :type async_req: bool, optional :param _preload_content: if False, the ApiResponse.data will @@ -1272,7 +1277,8 @@ def fake_property_enum_integer_serialize_with_http_info(self, outer_object_with_ _params = locals() _all_params = [ - 'outer_object_with_enum_property' + 'outer_object_with_enum_property', + 'param' ] _all_params.extend( [ @@ -1303,6 +1309,10 @@ def fake_property_enum_integer_serialize_with_http_info(self, outer_object_with_ # process the query parameters _query_params = [] + if _params.get('param') is not None: # noqa: E501 + _query_params.append(('param', _params['param'])) + _collection_formats['param'] = 'multi' + # process the header parameters _header_params = dict(_params.get('_headers', {})) # process the form parameters diff --git a/samples/openapi3/client/petstore/python/docs/EnumSerialization.md b/samples/openapi3/client/petstore/python/docs/EnumSerialization.md new file mode 100644 index 000000000000..68d6e8e23fde --- /dev/null +++ b/samples/openapi3/client/petstore/python/docs/EnumSerialization.md @@ -0,0 +1,11 @@ +# EnumSerialization + + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/openapi3/client/petstore/python/docs/FakeApi.md b/samples/openapi3/client/petstore/python/docs/FakeApi.md index 354a3ce7191f..b5183d1123a8 100644 --- a/samples/openapi3/client/petstore/python/docs/FakeApi.md +++ b/samples/openapi3/client/petstore/python/docs/FakeApi.md @@ -632,7 +632,7 @@ 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) # **fake_property_enum_integer_serialize** -> OuterObjectWithEnumProperty fake_property_enum_integer_serialize(outer_object_with_enum_property) +> OuterObjectWithEnumProperty fake_property_enum_integer_serialize(outer_object_with_enum_property, param=param) @@ -643,6 +643,7 @@ Test serialization of enum (int) properties with examples ```python import petstore_api +from petstore_api.models.outer_enum_integer import OuterEnumInteger from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty from petstore_api.rest import ApiException from pprint import pprint @@ -659,9 +660,10 @@ with petstore_api.ApiClient(configuration) as api_client: # Create an instance of the API class api_instance = petstore_api.FakeApi(api_client) outer_object_with_enum_property = petstore_api.OuterObjectWithEnumProperty() # OuterObjectWithEnumProperty | Input enum (int) as post body + param = [petstore_api.OuterEnumInteger()] # List[OuterEnumInteger] | (optional) try: - api_response = api_instance.fake_property_enum_integer_serialize(outer_object_with_enum_property) + api_response = api_instance.fake_property_enum_integer_serialize(outer_object_with_enum_property, param=param) print("The response of FakeApi->fake_property_enum_integer_serialize:\n") pprint(api_response) except Exception as e: @@ -676,6 +678,7 @@ with petstore_api.ApiClient(configuration) as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **outer_object_with_enum_property** | [**OuterObjectWithEnumProperty**](OuterObjectWithEnumProperty.md)| Input enum (int) as post body | + **param** | [**List[OuterEnumInteger]**](OuterEnumInteger.md)| | [optional] ### Return type diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py index 258954a0b6d3..04e5e9cd15cf 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py @@ -25,6 +25,7 @@ from petstore_api.models.file_schema_test_class import FileSchemaTestClass from petstore_api.models.health_check_result import HealthCheckResult from petstore_api.models.outer_composite import OuterComposite +from petstore_api.models.outer_enum_integer import OuterEnumInteger from petstore_api.models.outer_object_with_enum_property import OuterObjectWithEnumProperty from petstore_api.models.pet import Pet from petstore_api.models.tag import Tag @@ -2179,6 +2180,7 @@ def _fake_outer_string_serialize_serialize( def fake_property_enum_integer_serialize( self, outer_object_with_enum_property: Annotated[OuterObjectWithEnumProperty, Field(description="Input enum (int) as post body")], + param: Optional[List[OuterEnumInteger]] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -2198,6 +2200,8 @@ def fake_property_enum_integer_serialize( :param outer_object_with_enum_property: Input enum (int) as post body (required) :type outer_object_with_enum_property: OuterObjectWithEnumProperty + :param param: + :type param: List[OuterEnumInteger] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -2222,6 +2226,7 @@ def fake_property_enum_integer_serialize( _param = self._fake_property_enum_integer_serialize_serialize( outer_object_with_enum_property=outer_object_with_enum_property, + param=param, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -2246,6 +2251,7 @@ def fake_property_enum_integer_serialize( def fake_property_enum_integer_serialize_with_http_info( self, outer_object_with_enum_property: Annotated[OuterObjectWithEnumProperty, Field(description="Input enum (int) as post body")], + param: Optional[List[OuterEnumInteger]] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -2265,6 +2271,8 @@ def fake_property_enum_integer_serialize_with_http_info( :param outer_object_with_enum_property: Input enum (int) as post body (required) :type outer_object_with_enum_property: OuterObjectWithEnumProperty + :param param: + :type param: List[OuterEnumInteger] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -2289,6 +2297,7 @@ def fake_property_enum_integer_serialize_with_http_info( _param = self._fake_property_enum_integer_serialize_serialize( outer_object_with_enum_property=outer_object_with_enum_property, + param=param, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -2313,6 +2322,7 @@ def fake_property_enum_integer_serialize_with_http_info( def fake_property_enum_integer_serialize_without_preload_content( self, outer_object_with_enum_property: Annotated[OuterObjectWithEnumProperty, Field(description="Input enum (int) as post body")], + param: Optional[List[OuterEnumInteger]] = None, _request_timeout: Union[ None, Annotated[StrictFloat, Field(gt=0)], @@ -2332,6 +2342,8 @@ def fake_property_enum_integer_serialize_without_preload_content( :param outer_object_with_enum_property: Input enum (int) as post body (required) :type outer_object_with_enum_property: OuterObjectWithEnumProperty + :param param: + :type param: List[OuterEnumInteger] :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of @@ -2356,6 +2368,7 @@ def fake_property_enum_integer_serialize_without_preload_content( _param = self._fake_property_enum_integer_serialize_serialize( outer_object_with_enum_property=outer_object_with_enum_property, + param=param, _request_auth=_request_auth, _content_type=_content_type, _headers=_headers, @@ -2375,6 +2388,7 @@ def fake_property_enum_integer_serialize_without_preload_content( def _fake_property_enum_integer_serialize_serialize( self, outer_object_with_enum_property, + param, _request_auth, _content_type, _headers, @@ -2384,6 +2398,7 @@ def _fake_property_enum_integer_serialize_serialize( _host = None _collection_formats: Dict[str, str] = { + 'param': 'multi', } _path_params: Dict[str, str] = {} @@ -2395,6 +2410,10 @@ def _fake_property_enum_integer_serialize_serialize( # process the path parameters # process the query parameters + if param is not None: + + _query_params.append(('param', param)) + # process the header parameters # process the form parameters # process the body parameter diff --git a/samples/openapi3/client/petstore/python/petstore_api/api_client.py b/samples/openapi3/client/petstore/python/petstore_api/api_client.py index 18c5803cb5cf..7e17903a95fd 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api_client.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api_client.py @@ -350,6 +350,8 @@ def sanitize_for_serialization(self, obj): """ if obj is None: return None + elif isinstance(obj, Enum): + return obj.value elif isinstance(obj, SecretStr): return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): diff --git a/samples/openapi3/client/petstore/python/petstore_api/models/enum_serialization.py b/samples/openapi3/client/petstore/python/petstore_api/models/enum_serialization.py new file mode 100644 index 000000000000..b7177b7f380a --- /dev/null +++ b/samples/openapi3/client/petstore/python/petstore_api/models/enum_serialization.py @@ -0,0 +1,37 @@ +# 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 json +from enum import Enum +from typing_extensions import Self + + +class EnumSerialization(int, Enum): + """ + EnumSerialization + """ + + """ + allowed enum values + """ + NUMBER_0 = 0 + NUMBER_1 = 1 + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of EnumSerialization from a JSON string""" + return cls(json.loads(json_str)) + + diff --git a/samples/openapi3/client/petstore/python/test/test_enum_serialization.py b/samples/openapi3/client/petstore/python/test/test_enum_serialization.py new file mode 100644 index 000000000000..aca0106b36b9 --- /dev/null +++ b/samples/openapi3/client/petstore/python/test/test_enum_serialization.py @@ -0,0 +1,33 @@ +# 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 + + +import unittest + +from petstore_api.models.enum_serialization import EnumSerialization + +class TestEnumSerialization(unittest.TestCase): + """EnumSerialization unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testEnumSerialization(self): + """Test EnumSerialization""" + # inst = EnumSerialization() + +if __name__ == '__main__': + unittest.main() diff --git a/samples/openapi3/client/petstore/python/tests/test_api_client.py b/samples/openapi3/client/petstore/python/tests/test_api_client.py index 8c5a99d3acff..1d8ffebaca0a 100644 --- a/samples/openapi3/client/petstore/python/tests/test_api_client.py +++ b/samples/openapi3/client/petstore/python/tests/test_api_client.py @@ -9,11 +9,9 @@ $ pytest """ -import os -import time -import atexit -import weakref import unittest +from enum import Enum + from dateutil.parser import parse import petstore_api @@ -155,6 +153,16 @@ def test_sanitize_for_serialization_datetime(self): result = self.api_client.sanitize_for_serialization(data) self.assertEqual(result, "1997-07-16T19:20:30.450000+01:00") + def test_sanitize_for_serialization_list_enum(self): + class EnumSerialization(int, Enum): + NUMBER_0 = 0 + NUMBER_1 = 1 + + data = [EnumSerialization.NUMBER_1] + result = self.api_client.sanitize_for_serialization(data) + self.assertEqual(result, [1]) + self.assertNotIsInstance(result[0], EnumSerialization) + def test_sanitize_for_serialization_list(self): data = [1] result = self.api_client.sanitize_for_serialization(data) @@ -203,10 +211,11 @@ def test_parameters_to_url_query_simple_values(self): "category2": "example2" } result = self.api_client.parameters_to_url_query([('value', dictionary)], {}) - self.assertEqual(result, "value=%7B%22category%22%3A%20%22example%22%2C%20%22category2%22%3A%20%22example2%22%7D") - + self.assertEqual(result, + "value=%7B%22category%22%3A%20%22example%22%2C%20%22category2%22%3A%20%22example2%22%7D") + def test_parameters_to_url_query_complex_values(self): - data='value={"number": 1, "string": "str", "bool": true, "dict": {"number": 1, "string": "str", "bool": true}}' + data = 'value={"number": 1, "string": "str", "bool": true, "dict": {"number": 1, "string": "str", "bool": true}}' dictionary = { "number": 1, "string": "str", @@ -218,10 +227,11 @@ def test_parameters_to_url_query_complex_values(self): } } result = self.api_client.parameters_to_url_query([('value', dictionary)], {}) - self.assertEqual(result, 'value=%7B%22number%22%3A%201%2C%20%22string%22%3A%20%22str%22%2C%20%22bool%22%3A%20true%2C%20%22dict%22%3A%20%7B%22number%22%3A%201%2C%20%22string%22%3A%20%22str%22%2C%20%22bool%22%3A%20true%7D%7D') + self.assertEqual(result, + 'value=%7B%22number%22%3A%201%2C%20%22string%22%3A%20%22str%22%2C%20%22bool%22%3A%20true%2C%20%22dict%22%3A%20%7B%22number%22%3A%201%2C%20%22string%22%3A%20%22str%22%2C%20%22bool%22%3A%20true%7D%7D') def test_parameters_to_url_query_dict_values(self): - data='value={"strValues": ["one", "two", "three"], "dictValues": [{"name": "value1", "age": 14}, {"name": "value2", "age": 12}]}' + data = 'value={"strValues": ["one", "two", "three"], "dictValues": [{"name": "value1", "age": 14}, {"name": "value2", "age": 12}]}' dictionary = { "strValues": [ "one", @@ -240,12 +250,14 @@ def test_parameters_to_url_query_dict_values(self): ] } result = self.api_client.parameters_to_url_query([('value', dictionary)], {}) - self.assertEqual(result, 'value=%7B%22strValues%22%3A%20%5B%22one%22%2C%20%22two%22%2C%20%22three%22%5D%2C%20%22dictValues%22%3A%20%5B%7B%22name%22%3A%20%22value1%22%2C%20%22age%22%3A%2014%7D%2C%20%7B%22name%22%3A%20%22value2%22%2C%20%22age%22%3A%2012%7D%5D%7D') + self.assertEqual(result, + 'value=%7B%22strValues%22%3A%20%5B%22one%22%2C%20%22two%22%2C%20%22three%22%5D%2C%20%22dictValues%22%3A%20%5B%7B%22name%22%3A%20%22value1%22%2C%20%22age%22%3A%2014%7D%2C%20%7B%22name%22%3A%20%22value2%22%2C%20%22age%22%3A%2012%7D%5D%7D') def test_parameters_to_url_query_boolean_value(self): result = self.api_client.parameters_to_url_query([('boolean', True)], {}) self.assertEqual(result, "boolean=true") def test_parameters_to_url_query_list_value(self): - params = self.api_client.parameters_to_url_query(params=[('list', [1, 2, 3])], collection_formats={'list': 'multi'}) + params = self.api_client.parameters_to_url_query(params=[('list', [1, 2, 3])], + collection_formats={'list': 'multi'}) self.assertEqual(params, "list=1&list=2&list=3") diff --git a/samples/openapi3/client/petstore/python/tests/test_fake_api.py b/samples/openapi3/client/petstore/python/tests/test_fake_api.py index 5e48d09b040e..dec2dcb4954b 100644 --- a/samples/openapi3/client/petstore/python/tests/test_fake_api.py +++ b/samples/openapi3/client/petstore/python/tests/test_fake_api.py @@ -15,6 +15,8 @@ import unittest from unittest.mock import patch, Mock import petstore_api +from petstore_api import OuterObjectWithEnumProperty, OuterEnumInteger + class TestFakeApi(unittest.TestCase): """StrLikeJson unit test stubs""" @@ -141,4 +143,25 @@ def testByteLikeJson(self): "petstore_api.api_client.ApiClient.call_api", return_value=mock_resp ): returned = self.fake_api.fake_return_byte_like_json() - self.assertEqual(b'{"a": "a"}', returned) \ No newline at end of file + self.assertEqual(b'{"a": "a"}', returned) + + def testIntEnumReturnsValue(self): + """ + Fixes #18327 (https://github.com/OpenAPITools/openapi-generator/issues/18327) + The enum value should be used in the param and not the enum name + """ + mock_resp = Mock() + mock_resp.status = 200 + mock_resp.data = b'{"value": "0"}' + mock_resp.getheaders.return_value = {} + mock_resp.getheader = ( + lambda name: "text/plain" if name == "content-type" else Mock() + ) + with patch( + "petstore_api.api_client.ApiClient.call_api", return_value=mock_resp + ) as call_api_mock: + self.fake_api.fake_property_enum_integer_serialize( + outer_object_with_enum_property=OuterObjectWithEnumProperty(value=OuterEnumInteger.NUMBER_0), + param=[OuterEnumInteger.NUMBER_0]) + self.assertEqual(call_api_mock.call_args[0][1], + 'http://petstore.swagger.io:80/v2/fake/property/enum-int?param=0')