boto3-assist 0.5.0__tar.gz → 0.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/PKG-INFO +1 -1
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/pyproject.toml +1 -1
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cognito/user.py +8 -1
- boto3_assist-0.5.1/src/boto3_assist/models/serializable_model.py +30 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/utilities/serialization_utility.py +68 -26
- boto3_assist-0.5.1/src/boto3_assist/version.py +1 -0
- boto3_assist-0.5.1/tests/models/serializable_model_test.py +113 -0
- boto3_assist-0.5.1/tests/s3/__init__.py +0 -0
- boto3_assist-0.5.0/src/boto3_assist/version.py +0 -1
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/.env.docker +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/.env.docker.001 +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/.env.docker.nosql.workbench +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/.env.unittest +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/.gitignore +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/.vscode/launch.json +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/.vscode/settings.json +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/.vscode/tasks.json +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/LICENSE-EXPLAINED.txt +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/LICENSE.txt +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/README.md +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/aws_regions_with_status.csv +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/aws_regions_with_status.json +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/devops/build.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/devops/readme.md +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/__init__.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/cloudwatch/log_report.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/models/order_item_model.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/models/order_model.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/models/product_model.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/models/user_model.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/models/user_post_model.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/order_example/main.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/order_example/products.json +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/services/order_item_service.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/services/order_service.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/services/product_service.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/services/table_service.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/services/user_post_service.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/services/user_service.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/services/user_service_client_example.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/services/user_service_resource_example.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/user_post_example/main.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/ec2/regions_report.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/module-headers.txt +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/mypy.ini +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/requirements-dev.txt +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/requirements.txt +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/run-checks.sh +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/__init__.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/aws_lambda/event_info.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/boto3session.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cloudwatch/cloudwatch_connection.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cloudwatch/cloudwatch_connection_tracker.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cloudwatch/cloudwatch_log_connection.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cloudwatch/cloudwatch_logs.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cloudwatch/cloudwatch_query.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cognito/cognito_authorizer.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cognito/cognito_connection.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cognito/cognito_utility.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cognito/jwks_cache.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/connection.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/connection_tracker.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_connection.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_helpers.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_importer.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_index.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_iservice.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_key.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_model_base.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_model_base_interfaces.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_reindexer.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_reserved_words.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_reserved_words.txt +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/readme.md +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/troubleshooting.md +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/ec2/ec2_connection.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/environment_services/__init__.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/environment_services/environment_loader.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/environment_services/environment_variables.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/errors/custom_exceptions.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/http_status_codes.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/s3/s3.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/s3/s3_connection.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/utilities/datetime_utility.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/utilities/dictionaroy_utility.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/utilities/file_operations.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/utilities/http_utility.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/utilities/logging_utility.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/utilities/numbers_utility.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/utilities/string_utility.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/__init__.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/__top/__init__.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/__init__.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/dynamodb_model_base_test.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/dynamodb_model_projections_test.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/dynamodb_model_serializtion_test.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/dynamodb_moto_sorting_test.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/dynamodb_reindex_test.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/models/cms/base.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/models/cms/content_block.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/models/cms/page.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/models/cms/template.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/models/simple_model.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/models/user_model.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/models/user_required_fields_model.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/examples_test/__init__.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/examples_test/user_service_test.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/lambda/__init__.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/lambda/event_info_test.py +0 -0
- {boto3_assist-0.5.0/tests/s3 → boto3_assist-0.5.1/tests/models}/__init__.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/s3/files/test.txt +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/s3/s3_file_upload_test.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/utilities/__init__.py +0 -0
- {boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/utilities/serialization_utility_test.py +0 -0
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geek Cafe, LLC
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for the license information.
|
|
5
|
+
"""
|
|
6
|
+
|
|
1
7
|
from typing import Optional
|
|
8
|
+
from boto3_assist.models.serializable_model import SerializableModel
|
|
2
9
|
|
|
3
10
|
|
|
4
|
-
class CognitoUser:
|
|
11
|
+
class CognitoUser(SerializableModel):
|
|
5
12
|
"""A generic way to represent a cognito user"""
|
|
6
13
|
|
|
7
14
|
def __init__(
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geek Cafe, LLC
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for the license information.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
from typing import TypeVar
|
|
9
|
+
from boto3_assist.utilities.serialization_utility import Serialization
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SerializableModel:
|
|
13
|
+
"""Library to Serialize object to a DynamoDB Format"""
|
|
14
|
+
|
|
15
|
+
T = TypeVar("T", bound="SerializableModel")
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def map(source: dict | object, target: T, coerce: bool = True) -> T:
|
|
19
|
+
"""
|
|
20
|
+
Map the source dictionary to the target object.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
- source: The dictionary to map from.
|
|
24
|
+
- target: The object to map to.
|
|
25
|
+
"""
|
|
26
|
+
mapped = Serialization.map(source, target, coerce=coerce)
|
|
27
|
+
if mapped is None:
|
|
28
|
+
raise ValueError("Unable to map source to target")
|
|
29
|
+
|
|
30
|
+
return mapped
|
{boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/utilities/serialization_utility.py
RENAMED
|
@@ -5,11 +5,11 @@ from decimal import Decimal
|
|
|
5
5
|
from typing import Dict, List, TypeVar
|
|
6
6
|
import json
|
|
7
7
|
import jsons
|
|
8
|
-
from aws_lambda_powertools import Logger
|
|
8
|
+
from aws_lambda_powertools import Logger
|
|
9
9
|
|
|
10
10
|
T = TypeVar("T")
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
logger = Logger()
|
|
14
14
|
|
|
15
15
|
|
|
@@ -67,7 +67,7 @@ class Serialization:
|
|
|
67
67
|
raise ValueError("Unable to convert object to dictionary")
|
|
68
68
|
|
|
69
69
|
@staticmethod
|
|
70
|
-
def map(source: object, target: T) -> T | None:
|
|
70
|
+
def map(source: object, target: T, coerce: bool = True) -> T | None:
|
|
71
71
|
"""Map an object from one object to another"""
|
|
72
72
|
source_dict: dict | object
|
|
73
73
|
if isinstance(source, dict):
|
|
@@ -76,12 +76,26 @@ class Serialization:
|
|
|
76
76
|
source_dict = Serialization.convert_object_to_dict(source)
|
|
77
77
|
if not isinstance(source_dict, dict):
|
|
78
78
|
return None
|
|
79
|
-
return Serialization.load_properties(
|
|
79
|
+
return Serialization.load_properties(
|
|
80
|
+
source=source_dict, target=target, coerce=coerce
|
|
81
|
+
)
|
|
80
82
|
|
|
81
83
|
@staticmethod
|
|
82
|
-
def load_properties(
|
|
84
|
+
def load_properties(
|
|
85
|
+
source: dict,
|
|
86
|
+
target: T,
|
|
87
|
+
coerce: bool = True,
|
|
88
|
+
) -> T | None:
|
|
83
89
|
"""
|
|
84
|
-
Converts a source to
|
|
90
|
+
Converts a source dictionary to a target object.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
source (dict): The source dictionary containing properties.
|
|
94
|
+
target (T): The target object to populate.
|
|
95
|
+
coerce (bool): If True, attempts to convert values to the target attribute types. If False, raises an error for type mismatches.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
T | None: The populated target object, or None if an error occurred.
|
|
85
99
|
"""
|
|
86
100
|
# Ensure target is an instance of the class
|
|
87
101
|
if isinstance(target, type):
|
|
@@ -95,28 +109,56 @@ class Serialization:
|
|
|
95
109
|
setattr(target, "__actively_serializing_data__", True)
|
|
96
110
|
|
|
97
111
|
for key, value in source.items():
|
|
98
|
-
if Serialization.has_attribute(target, key):
|
|
112
|
+
if Serialization.has_attribute(target, key):
|
|
99
113
|
attr = getattr(target, key)
|
|
100
|
-
|
|
101
|
-
|
|
114
|
+
expected_type = type(attr)
|
|
115
|
+
|
|
116
|
+
try:
|
|
117
|
+
if isinstance(attr, (int, float, str, bool)):
|
|
118
|
+
if not isinstance(value, expected_type):
|
|
119
|
+
if coerce:
|
|
120
|
+
# Attempt to coerce the value to the expected type
|
|
121
|
+
try:
|
|
122
|
+
value = expected_type(value)
|
|
123
|
+
except ValueError as e:
|
|
124
|
+
logger.warning(
|
|
125
|
+
f"Warning coercing attribute {key} with value {value}: {e}"
|
|
126
|
+
)
|
|
127
|
+
# TODO: should we set numbers to 0 or a NaN or raise an error
|
|
128
|
+
|
|
129
|
+
setattr(target, key, value)
|
|
130
|
+
# raise ValueError( # pylint: disable=w0707
|
|
131
|
+
# f"Type mismatch for attribute {key}. Expected {expected_type}, got {type(value)}."
|
|
132
|
+
# )
|
|
133
|
+
else:
|
|
134
|
+
raise ValueError(
|
|
135
|
+
f"Type mismatch for attribute {key}. Expected {expected_type}, got {type(value)}."
|
|
136
|
+
)
|
|
137
|
+
setattr(target, key, value)
|
|
138
|
+
elif isinstance(attr, type(None)):
|
|
139
|
+
setattr(target, key, value)
|
|
140
|
+
elif isinstance(attr, list) and isinstance(value, list):
|
|
141
|
+
attr.clear()
|
|
142
|
+
attr.extend(value)
|
|
143
|
+
elif isinstance(attr, dict) and isinstance(value, dict):
|
|
144
|
+
Serialization.load_properties(value, attr, coerce=coerce)
|
|
145
|
+
elif hasattr(attr, "__dict__") and isinstance(value, dict):
|
|
146
|
+
Serialization.load_properties(value, attr, coerce=coerce)
|
|
147
|
+
else:
|
|
102
148
|
setattr(target, key, value)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
elif hasattr(attr, "__dict__") and isinstance(value, dict):
|
|
117
|
-
Serialization.load_properties(value, attr)
|
|
118
|
-
else:
|
|
119
|
-
setattr(target, key, value)
|
|
149
|
+
except ValueError as e:
|
|
150
|
+
logger.error(
|
|
151
|
+
f"Error setting attribute {key} with value {value}: {e}"
|
|
152
|
+
)
|
|
153
|
+
raise
|
|
154
|
+
except Exception as e: # pylint: disable=w0718
|
|
155
|
+
logger.error(
|
|
156
|
+
f"Error setting attribute {key} with value {value}: {e}. "
|
|
157
|
+
"This usually occurs on properties that don't have setters. "
|
|
158
|
+
"You can add a setter (even with a pass action) for this property, "
|
|
159
|
+
"decorate it with the @exclude_from_serialization "
|
|
160
|
+
"or ignore this error. "
|
|
161
|
+
)
|
|
120
162
|
|
|
121
163
|
if hasattr(target, "__actively_serializing_data__"):
|
|
122
164
|
setattr(target, "__actively_serializing_data__", False)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.5.1'
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geek Cafe, LLC
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for the license information.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import unittest
|
|
8
|
+
from typing import Dict
|
|
9
|
+
from boto3_assist.models.serializable_model import SerializableModel
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ExampleModel(SerializableModel):
|
|
13
|
+
"""A model that inherits the serializable"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, name: str = "", age: int = 0, active: bool = False):
|
|
16
|
+
self.name = name
|
|
17
|
+
self.age = age
|
|
18
|
+
self.active = active
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TestSerializableModel(unittest.TestCase):
|
|
22
|
+
"""Testing Serialzing Models"""
|
|
23
|
+
|
|
24
|
+
def setUp(self) -> None:
|
|
25
|
+
self.source_dict: Dict[str, any] = {
|
|
26
|
+
"name": "John Doe",
|
|
27
|
+
"age": 30,
|
|
28
|
+
"active": True,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
self.target_object = ExampleModel()
|
|
32
|
+
|
|
33
|
+
def test_map_valid_data(self):
|
|
34
|
+
"""
|
|
35
|
+
Test mapping a valid dictionary to an object instance.
|
|
36
|
+
"""
|
|
37
|
+
result = ExampleModel.map(self.source_dict, self.target_object)
|
|
38
|
+
|
|
39
|
+
self.assertEqual(result.name, "John Doe")
|
|
40
|
+
self.assertEqual(result.age, 30)
|
|
41
|
+
self.assertEqual(result.active, True)
|
|
42
|
+
|
|
43
|
+
def test_map_partial_data(self):
|
|
44
|
+
"""
|
|
45
|
+
Test mapping a dictionary with partial data.
|
|
46
|
+
"""
|
|
47
|
+
partial_dict = {"name": "Jane Doe"}
|
|
48
|
+
result = ExampleModel.map(partial_dict, self.target_object)
|
|
49
|
+
|
|
50
|
+
self.assertEqual(result.name, "Jane Doe")
|
|
51
|
+
self.assertEqual(result.age, 0) # Default value
|
|
52
|
+
self.assertEqual(result.active, False) # Default value
|
|
53
|
+
|
|
54
|
+
def test_map_empty_data(self):
|
|
55
|
+
"""
|
|
56
|
+
Test mapping an empty dictionary.
|
|
57
|
+
"""
|
|
58
|
+
empty_dict = {}
|
|
59
|
+
result = ExampleModel.map(empty_dict, self.target_object)
|
|
60
|
+
|
|
61
|
+
self.assertEqual(result.name, "") # Default value
|
|
62
|
+
self.assertEqual(result.age, 0) # Default value
|
|
63
|
+
self.assertEqual(result.active, False) # Default value
|
|
64
|
+
|
|
65
|
+
def test_map_invalid_data(self):
|
|
66
|
+
"""
|
|
67
|
+
Test mapping a dictionary with invalid data types.
|
|
68
|
+
"""
|
|
69
|
+
invalid_dict = {"name": 123, "age": "thirty", "active": "yes"}
|
|
70
|
+
|
|
71
|
+
with self.assertRaises(ValueError):
|
|
72
|
+
ExampleModel.map(invalid_dict, self.target_object, coerce=False)
|
|
73
|
+
|
|
74
|
+
def test_map_invalid_data_coerce_with_failure(self):
|
|
75
|
+
"""
|
|
76
|
+
Test mapping a dictionary with invalid data types.
|
|
77
|
+
"""
|
|
78
|
+
invalid_dict = {"name": 123, "age": "thirty", "active": "yes"}
|
|
79
|
+
|
|
80
|
+
result = ExampleModel.map(invalid_dict, self.target_object)
|
|
81
|
+
|
|
82
|
+
self.assertEqual(result.name, "123")
|
|
83
|
+
# currently we're allowing this to happen
|
|
84
|
+
self.assertEqual(result.age, "thirty")
|
|
85
|
+
self.assertEqual(result.active, True)
|
|
86
|
+
|
|
87
|
+
def test_map_invalid_data_coerce(self):
|
|
88
|
+
"""
|
|
89
|
+
Test mapping a dictionary with invalid data types.
|
|
90
|
+
"""
|
|
91
|
+
invalid_dict = {"name": 123, "age": 30, "active": "yes"}
|
|
92
|
+
|
|
93
|
+
result = ExampleModel.map(invalid_dict, self.target_object)
|
|
94
|
+
|
|
95
|
+
self.assertEqual(result.name, "123")
|
|
96
|
+
self.assertEqual(result.age, 30)
|
|
97
|
+
self.assertEqual(result.active, True)
|
|
98
|
+
|
|
99
|
+
def test_map_non_dict_source(self):
|
|
100
|
+
"""
|
|
101
|
+
Test mapping from a non-dictionary source object.
|
|
102
|
+
"""
|
|
103
|
+
source_object = ExampleModel(name="Alice", age=25, active=True)
|
|
104
|
+
|
|
105
|
+
result = ExampleModel.map(source_object, self.target_object)
|
|
106
|
+
|
|
107
|
+
self.assertEqual(result.name, "Alice")
|
|
108
|
+
self.assertEqual(result.age, 25)
|
|
109
|
+
self.assertEqual(result.active, True)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
if __name__ == "__main__":
|
|
113
|
+
unittest.main()
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.5.0'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.5.0 → boto3_assist-0.5.1}/examples/dynamodb/services/user_service_client_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cloudwatch/cloudwatch_connection.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/cloudwatch/cloudwatch_log_connection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_reserved_words.py
RENAMED
|
File without changes
|
{boto3_assist-0.5.0 → boto3_assist-0.5.1}/src/boto3_assist/dynamodb/dynamodb_reserved_words.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/dynamodb_model_serializtion_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.5.0 → boto3_assist-0.5.1}/tests/dynamodb/models/user_required_fields_model.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|