Fix problem in sanitize_for_serialization for Python (pydantic type SecretStr ) BUG#16086 (2nd pull) (#18023)

* fix-for-bug-16086

* add to_dict alternative

* fix assertEqual

* remove extra blank line + test_model Argument SecretStr set

* update samples / remove extra blank line

* restore sanitize test for serialization with different data types

* remove empty line in api_client.mustache

* remove 2nd empty line in api_client.mustache
This commit is contained in:
Artur Zdolinski
2024-03-20 12:14:43 +01:00
committed by GitHub
parent e2df0d6154
commit c15e267e22
6 changed files with 50 additions and 7 deletions

View File

@@ -13,6 +13,7 @@ import tempfile
from urllib.parse import quote from urllib.parse import quote
from typing import Tuple, Optional, List, Dict, Union from typing import Tuple, Optional, List, Dict, Union
from pydantic import SecretStr
{{#tornado}} {{#tornado}}
import tornado.gen import tornado.gen
{{/tornado}} {{/tornado}}
@@ -344,6 +345,7 @@ class ApiClient:
"""Builds a JSON POST object. """Builds a JSON POST object.
If obj is None, return None. 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 str, int, long, float, bool, return directly.
If obj is datetime.datetime, datetime.date If obj is datetime.datetime, datetime.date
convert to string in iso8601 format. convert to string in iso8601 format.
@@ -356,6 +358,8 @@ class ApiClient:
""" """
if obj is None: if obj is None:
return None return None
elif isinstance(obj, SecretStr):
return obj.get_secret_value()
elif isinstance(obj, self.PRIMITIVE_TYPES): elif isinstance(obj, self.PRIMITIVE_TYPES):
return obj return obj
elif isinstance(obj, list): elif isinstance(obj, list):
@@ -377,7 +381,10 @@ class ApiClient:
# and attributes which value is not None. # and attributes which value is not None.
# Convert attribute name to json key in # Convert attribute name to json key in
# model definition for request. # 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 { return {
key: self.sanitize_for_serialization(val) key: self.sanitize_for_serialization(val)

View File

@@ -24,6 +24,7 @@ import tempfile
from urllib.parse import quote from urllib.parse import quote
from typing import Tuple, Optional, List, Dict, Union from typing import Tuple, Optional, List, Dict, Union
from pydantic import SecretStr
from openapi_client.configuration import Configuration from openapi_client.configuration import Configuration
from openapi_client.api_response import ApiResponse, T as ApiResponseT from openapi_client.api_response import ApiResponse, T as ApiResponseT
@@ -337,6 +338,7 @@ class ApiClient:
"""Builds a JSON POST object. """Builds a JSON POST object.
If obj is None, return None. 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 str, int, long, float, bool, return directly.
If obj is datetime.datetime, datetime.date If obj is datetime.datetime, datetime.date
convert to string in iso8601 format. convert to string in iso8601 format.
@@ -349,6 +351,8 @@ class ApiClient:
""" """
if obj is None: if obj is None:
return None return None
elif isinstance(obj, SecretStr):
return obj.get_secret_value()
elif isinstance(obj, self.PRIMITIVE_TYPES): elif isinstance(obj, self.PRIMITIVE_TYPES):
return obj return obj
elif isinstance(obj, list): elif isinstance(obj, list):
@@ -370,7 +374,10 @@ class ApiClient:
# and attributes which value is not None. # and attributes which value is not None.
# Convert attribute name to json key in # Convert attribute name to json key in
# model definition for request. # 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 { return {
key: self.sanitize_for_serialization(val) key: self.sanitize_for_serialization(val)

View File

@@ -24,6 +24,7 @@ import tempfile
from urllib.parse import quote from urllib.parse import quote
from typing import Tuple, Optional, List, Dict, Union from typing import Tuple, Optional, List, Dict, Union
from pydantic import SecretStr
from openapi_client.configuration import Configuration from openapi_client.configuration import Configuration
from openapi_client.api_response import ApiResponse, T as ApiResponseT from openapi_client.api_response import ApiResponse, T as ApiResponseT
@@ -337,6 +338,7 @@ class ApiClient:
"""Builds a JSON POST object. """Builds a JSON POST object.
If obj is None, return None. 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 str, int, long, float, bool, return directly.
If obj is datetime.datetime, datetime.date If obj is datetime.datetime, datetime.date
convert to string in iso8601 format. convert to string in iso8601 format.
@@ -349,6 +351,8 @@ class ApiClient:
""" """
if obj is None: if obj is None:
return None return None
elif isinstance(obj, SecretStr):
return obj.get_secret_value()
elif isinstance(obj, self.PRIMITIVE_TYPES): elif isinstance(obj, self.PRIMITIVE_TYPES):
return obj return obj
elif isinstance(obj, list): elif isinstance(obj, list):
@@ -370,7 +374,10 @@ class ApiClient:
# and attributes which value is not None. # and attributes which value is not None.
# Convert attribute name to json key in # Convert attribute name to json key in
# model definition for request. # 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 { return {
key: self.sanitize_for_serialization(val) key: self.sanitize_for_serialization(val)

View File

@@ -23,6 +23,7 @@ import tempfile
from urllib.parse import quote from urllib.parse import quote
from typing import Tuple, Optional, List, Dict, Union from typing import Tuple, Optional, List, Dict, Union
from pydantic import SecretStr
from petstore_api.configuration import Configuration from petstore_api.configuration import Configuration
from petstore_api.api_response import ApiResponse, T as ApiResponseT from petstore_api.api_response import ApiResponse, T as ApiResponseT
@@ -339,6 +340,7 @@ class ApiClient:
"""Builds a JSON POST object. """Builds a JSON POST object.
If obj is None, return None. 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 str, int, long, float, bool, return directly.
If obj is datetime.datetime, datetime.date If obj is datetime.datetime, datetime.date
convert to string in iso8601 format. convert to string in iso8601 format.
@@ -351,6 +353,8 @@ class ApiClient:
""" """
if obj is None: if obj is None:
return None return None
elif isinstance(obj, SecretStr):
return obj.get_secret_value()
elif isinstance(obj, self.PRIMITIVE_TYPES): elif isinstance(obj, self.PRIMITIVE_TYPES):
return obj return obj
elif isinstance(obj, list): elif isinstance(obj, list):
@@ -372,7 +376,10 @@ class ApiClient:
# and attributes which value is not None. # and attributes which value is not None.
# Convert attribute name to json key in # Convert attribute name to json key in
# model definition for request. # 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 { return {
key: self.sanitize_for_serialization(val) key: self.sanitize_for_serialization(val)

View File

@@ -23,6 +23,7 @@ import tempfile
from urllib.parse import quote from urllib.parse import quote
from typing import Tuple, Optional, List, Dict, Union from typing import Tuple, Optional, List, Dict, Union
from pydantic import SecretStr
from petstore_api.configuration import Configuration from petstore_api.configuration import Configuration
from petstore_api.api_response import ApiResponse, T as ApiResponseT from petstore_api.api_response import ApiResponse, T as ApiResponseT
@@ -336,6 +337,7 @@ class ApiClient:
"""Builds a JSON POST object. """Builds a JSON POST object.
If obj is None, return None. 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 str, int, long, float, bool, return directly.
If obj is datetime.datetime, datetime.date If obj is datetime.datetime, datetime.date
convert to string in iso8601 format. convert to string in iso8601 format.
@@ -348,6 +350,8 @@ class ApiClient:
""" """
if obj is None: if obj is None:
return None return None
elif isinstance(obj, SecretStr):
return obj.get_secret_value()
elif isinstance(obj, self.PRIMITIVE_TYPES): elif isinstance(obj, self.PRIMITIVE_TYPES):
return obj return obj
elif isinstance(obj, list): elif isinstance(obj, list):
@@ -369,7 +373,10 @@ class ApiClient:
# and attributes which value is not None. # and attributes which value is not None.
# Convert attribute name to json key in # Convert attribute name to json key in
# model definition for request. # 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 { return {
key: self.sanitize_for_serialization(val) key: self.sanitize_for_serialization(val)

View File

@@ -8,7 +8,7 @@ import os
import time import time
import unittest import unittest
from pydantic import ValidationError from pydantic import ValidationError, SecretStr, BaseModel, StrictStr, Field
import pytest import pytest
import petstore_api import petstore_api
@@ -407,9 +407,17 @@ class ModelTests(unittest.TestCase):
a.pattern_with_digits_and_delimiter = "image_123" a.pattern_with_digits_and_delimiter = "image_123"
self.assertEqual(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'}) 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): def test_inline_enum_validator(self):
self.pet = petstore_api.Pet(name="test name", photoUrls=["string"]) self.pet = petstore_api.Pet(name="test name", photoUrls=["string"])
self.pet.id = 1 self.pet.id = 1