Skip to content
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

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

Merged
merged 22 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
800241d
fix-for-bug-16086
azdolinski Mar 2, 2024
8e20da6
add to_dict alternative
azdolinski Mar 2, 2024
137ff31
fix assertEqual
azdolinski Mar 2, 2024
9879006
Merge pull request #2 from azdolinski/bug_16086
azdolinski Mar 4, 2024
b5e7bd4
Merge branch 'OpenAPITools:master' into master
azdolinski Mar 5, 2024
5f8e6ba
Merge branch 'OpenAPITools:master' into master
azdolinski Mar 6, 2024
737e711
remove extra blank line + test_model Argument SecretStr set
azdolinski Mar 9, 2024
9238ea0
Merge branch 'OpenAPITools:master' into bug_16086
azdolinski Mar 9, 2024
0bf6031
Merge branch 'OpenAPITools:master' into master
azdolinski Mar 9, 2024
0abbe94
Merge branch 'master' into bug_16086
azdolinski Mar 9, 2024
067ecef
Merge pull request #3 from azdolinski/bug_16086
azdolinski Mar 10, 2024
5afc2d4
update samples / remove extra blank line
azdolinski Mar 10, 2024
9f0f2cb
Merge pull request #4 from azdolinski/bug_16086
azdolinski Mar 10, 2024
8058458
Merge branch 'OpenAPITools:master' into master
azdolinski Mar 10, 2024
4c3247f
Merge branch 'OpenAPITools:master' into bug_16086
azdolinski Mar 10, 2024
0ed3ba4
restore sanitize test for serialization with different data types
azdolinski Mar 10, 2024
b26fc96
Merge pull request #5 from azdolinski/bug_16086
azdolinski Mar 10, 2024
ceed176
Merge branch 'master' into master
azdolinski Mar 13, 2024
45a94dc
remove empty line in api_client.mustache
azdolinski Mar 13, 2024
6b8f27d
remove 2nd empty line in api_client.mustache
azdolinski Mar 13, 2024
045bc2e
Merge branch 'OpenAPITools:master' into master
azdolinski Mar 13, 2024
14c5972
Merge branch 'OpenAPITools:master' into master
azdolinski Mar 15, 2024
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 @@ -13,6 +13,8 @@ import tempfile

from urllib.parse import quote
from typing import Tuple, Optional, List, Dict
from pydantic import SecretStr

{{#tornado}}
import tornado.gen
{{/tornado}}
Expand Down Expand Up @@ -340,6 +342,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.
Expand All @@ -352,6 +355,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):
Expand All @@ -373,7 +378,11 @@ 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

from urllib.parse import quote
from typing import Tuple, Optional, List, Dict
from pydantic import SecretStr


from openapi_client.configuration import Configuration
from openapi_client.api_response import ApiResponse, T as ApiResponseT
Expand Down Expand Up @@ -333,6 +335,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.
Expand All @@ -345,6 +348,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):
Expand All @@ -366,7 +371,11 @@ 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')):

Copy link
Member

@wing328 wing328 Mar 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please remove this extra blank line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please remove this extra blank line?

done

obj_dict = obj.to_dict()
else:
obj_dict = obj.__dict__

return {
key: self.sanitize_for_serialization(val)
Expand Down
11 changes: 10 additions & 1 deletion samples/client/echo_api/python/openapi_client/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

from urllib.parse import quote
from typing import Tuple, Optional, List, Dict
from pydantic import SecretStr


from openapi_client.configuration import Configuration
from openapi_client.api_response import ApiResponse, T as ApiResponseT
Expand Down Expand Up @@ -333,6 +335,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.
Expand All @@ -345,6 +348,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):
Expand All @@ -366,7 +371,11 @@ 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

from urllib.parse import quote
from typing import Tuple, Optional, List, Dict
from pydantic import SecretStr


from petstore_api.configuration import Configuration
from petstore_api.api_response import ApiResponse, T as ApiResponseT
Expand Down Expand Up @@ -335,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.
Expand All @@ -347,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):
Expand All @@ -368,7 +373,11 @@ 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

from urllib.parse import quote
from typing import Tuple, Optional, List, Dict
from pydantic import SecretStr


from petstore_api.configuration import Configuration
from petstore_api.api_response import ApiResponse, T as ApiResponseT
Expand Down Expand Up @@ -332,6 +334,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.
Expand All @@ -344,6 +347,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):
Expand All @@ -365,7 +370,11 @@ 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)
Expand Down
9 changes: 7 additions & 2 deletions samples/openapi3/client/petstore/python/tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -408,7 +408,12 @@ def test_valdiator(self):
self.assertEqual(a.pattern_with_digits_and_delimiter, "image_123")

# test sanitize for serializaation with SecretStr (format: password)
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'})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for adding another test below

shouldn't this test/assertion still pass after this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this test/assertion still pass after this change?

yes, you are right... it can make sense to keep this line also as in case of password which will be as default string - it will also work. I added this line back to this pull.. 0ed3ba4 + will check sanitize function based on bytes/date/integer data types

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wing328 - can you please check and confirm that now is ok?

class LoginTest(BaseModel):
username: StrictStr = Field(min_length=2, strict=True, max_length=64)
password: SecretStr

l = LoginTest(username="admin", password="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"])
Expand Down
Loading