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 2ae005378fac..67395798dde6 100644 --- a/modules/openapi-generator/src/main/resources/python/api_client.mustache +++ b/modules/openapi-generator/src/main/resources/python/api_client.mustache @@ -13,6 +13,7 @@ import tempfile from urllib.parse import quote from typing import Tuple, Optional, List, Dict, Union +from pydantic import SecretStr {{#tornado}} import tornado.gen {{/tornado}} @@ -344,6 +345,7 @@ class ApiClient: """Builds a JSON POST object. If obj is None, return None. + If obj is SecretStr, return obj.get_secret_value() If obj is str, int, long, float, bool, return directly. If obj is datetime.datetime, datetime.date convert to string in iso8601 format. @@ -356,6 +358,8 @@ class ApiClient: """ if obj is None: return None + elif isinstance(obj, SecretStr): + return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): return obj elif isinstance(obj, list): @@ -377,7 +381,10 @@ class ApiClient: # and attributes which value is not None. # Convert attribute name to json key in # model definition for request. - obj_dict = obj.to_dict() + if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): + obj_dict = obj.to_dict() + else: + obj_dict = obj.__dict__ return { key: self.sanitize_for_serialization(val) 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 4b31ba81410b..b03fdf002669 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 @@ -24,6 +24,7 @@ from urllib.parse import quote from typing import Tuple, Optional, List, Dict, Union +from pydantic import SecretStr from openapi_client.configuration import Configuration from openapi_client.api_response import ApiResponse, T as ApiResponseT @@ -337,6 +338,7 @@ def sanitize_for_serialization(self, obj): """Builds a JSON POST object. If obj is None, return None. + If obj is SecretStr, return obj.get_secret_value() If obj is str, int, long, float, bool, return directly. If obj is datetime.datetime, datetime.date convert to string in iso8601 format. @@ -349,6 +351,8 @@ def sanitize_for_serialization(self, obj): """ if obj is None: return None + elif isinstance(obj, SecretStr): + return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): return obj elif isinstance(obj, list): @@ -370,7 +374,10 @@ def sanitize_for_serialization(self, obj): # and attributes which value is not None. # Convert attribute name to json key in # model definition for request. - obj_dict = obj.to_dict() + if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): + obj_dict = obj.to_dict() + else: + obj_dict = obj.__dict__ return { key: self.sanitize_for_serialization(val) 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 4b31ba81410b..b03fdf002669 100644 --- a/samples/client/echo_api/python/openapi_client/api_client.py +++ b/samples/client/echo_api/python/openapi_client/api_client.py @@ -24,6 +24,7 @@ from urllib.parse import quote from typing import Tuple, Optional, List, Dict, Union +from pydantic import SecretStr from openapi_client.configuration import Configuration from openapi_client.api_response import ApiResponse, T as ApiResponseT @@ -337,6 +338,7 @@ def sanitize_for_serialization(self, obj): """Builds a JSON POST object. If obj is None, return None. + If obj is SecretStr, return obj.get_secret_value() If obj is str, int, long, float, bool, return directly. If obj is datetime.datetime, datetime.date convert to string in iso8601 format. @@ -349,6 +351,8 @@ def sanitize_for_serialization(self, obj): """ if obj is None: return None + elif isinstance(obj, SecretStr): + return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): return obj elif isinstance(obj, list): @@ -370,7 +374,10 @@ def sanitize_for_serialization(self, obj): # and attributes which value is not None. # Convert attribute name to json key in # model definition for request. - obj_dict = obj.to_dict() + if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): + obj_dict = obj.to_dict() + else: + obj_dict = obj.__dict__ return { key: self.sanitize_for_serialization(val) 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 805773a9440e..0d941bcd0e48 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 @@ -23,6 +23,7 @@ from urllib.parse import quote from typing import Tuple, Optional, List, Dict, Union +from pydantic import SecretStr from petstore_api.configuration import Configuration from petstore_api.api_response import ApiResponse, T as ApiResponseT @@ -339,6 +340,7 @@ def sanitize_for_serialization(self, obj): """Builds a JSON POST object. If obj is None, return None. + If obj is SecretStr, return obj.get_secret_value() If obj is str, int, long, float, bool, return directly. If obj is datetime.datetime, datetime.date convert to string in iso8601 format. @@ -351,6 +353,8 @@ def sanitize_for_serialization(self, obj): """ if obj is None: return None + elif isinstance(obj, SecretStr): + return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): return obj elif isinstance(obj, list): @@ -372,7 +376,10 @@ def sanitize_for_serialization(self, obj): # and attributes which value is not None. # Convert attribute name to json key in # model definition for request. - obj_dict = obj.to_dict() + if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): + obj_dict = obj.to_dict() + else: + obj_dict = obj.__dict__ return { key: self.sanitize_for_serialization(val) 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 4ae5a65c91f4..18c5803cb5cf 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api_client.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api_client.py @@ -23,6 +23,7 @@ from urllib.parse import quote from typing import Tuple, Optional, List, Dict, Union +from pydantic import SecretStr from petstore_api.configuration import Configuration from petstore_api.api_response import ApiResponse, T as ApiResponseT @@ -336,6 +337,7 @@ def sanitize_for_serialization(self, obj): """Builds a JSON POST object. If obj is None, return None. + If obj is SecretStr, return obj.get_secret_value() If obj is str, int, long, float, bool, return directly. If obj is datetime.datetime, datetime.date convert to string in iso8601 format. @@ -348,6 +350,8 @@ def sanitize_for_serialization(self, obj): """ if obj is None: return None + elif isinstance(obj, SecretStr): + return obj.get_secret_value() elif isinstance(obj, self.PRIMITIVE_TYPES): return obj elif isinstance(obj, list): @@ -369,7 +373,10 @@ def sanitize_for_serialization(self, obj): # and attributes which value is not None. # Convert attribute name to json key in # model definition for request. - obj_dict = obj.to_dict() + if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): + obj_dict = obj.to_dict() + else: + obj_dict = obj.__dict__ return { key: self.sanitize_for_serialization(val) diff --git a/samples/openapi3/client/petstore/python/tests/test_model.py b/samples/openapi3/client/petstore/python/tests/test_model.py index 9ca69d0a53c5..1d3c29e2f4a1 100644 --- a/samples/openapi3/client/petstore/python/tests/test_model.py +++ b/samples/openapi3/client/petstore/python/tests/test_model.py @@ -8,7 +8,7 @@ import time import unittest -from pydantic import ValidationError +from pydantic import ValidationError, SecretStr, BaseModel, StrictStr, Field import pytest import petstore_api @@ -407,9 +407,17 @@ def test_valdiator(self): a.pattern_with_digits_and_delimiter = "image_123" self.assertEqual(a.pattern_with_digits_and_delimiter, "image_123") - # test sanitize for serializaation with SecretStr (format: password) + # test sanitize for serialization with different data types self.assertEquals(petstore_api.ApiClient().sanitize_for_serialization(a), {'byte': b'string', 'date': '2013-09-17', 'number': 123.45, 'password': 'testing09876', 'pattern_with_digits_and_delimiter': 'image_123'}) + # test sanitize for serialization with SecretStr (format: password) + class LoginTest(BaseModel): + username: StrictStr = Field(min_length=2, strict=True, max_length=64) + password: SecretStr + + l = LoginTest(username="admin", password=SecretStr("testing09876")) + self.assertEqual(petstore_api.ApiClient().sanitize_for_serialization(l), {'username': "admin", 'password': "testing09876"}) + def test_inline_enum_validator(self): self.pet = petstore_api.Pet(name="test name", photoUrls=["string"]) self.pet.id = 1