boto3-assist 0.10.0__tar.gz → 0.11.0__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.
Files changed (133) hide show
  1. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/.vscode/settings.json +3 -3
  2. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/PKG-INFO +9 -2
  3. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/README.md +4 -0
  4. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/pyproject.toml +5 -2
  5. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/requirements-dev.txt +2 -1
  6. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/cloudwatch/cloudwatch_connection_tracker.py +1 -1
  7. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/cognito/cognito_utility.py +13 -13
  8. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_model_base.py +1 -0
  9. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/s3/s3_event_data.py +7 -7
  10. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/s3/s3_object.py +2 -2
  11. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/securityhub/securityhub.py +2 -2
  12. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/utilities/serialization_utility.py +9 -4
  13. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/utilities/string_utility.py +1 -0
  14. boto3_assist-0.11.0/src/boto3_assist/version.py +1 -0
  15. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/cms/content_block.py +1 -1
  16. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/cms/page.py +1 -1
  17. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/cms/template.py +1 -1
  18. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dynamodb_model_base_test.py +1 -1
  19. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dynamodb_model_projections_test.py +2 -2
  20. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dynamodb_model_serializtion_test.py +2 -2
  21. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dynamodb_moto_sorting_test.py +2 -4
  22. boto3_assist-0.11.0/tests/models_tests/models/person.py +26 -0
  23. boto3_assist-0.11.0/tests/models_tests/models/user.py +66 -0
  24. boto3_assist-0.10.0/tests/models/serializable_model_test.py → boto3_assist-0.11.0/tests/models_tests/serializable_model_person_test.py +11 -26
  25. boto3_assist-0.11.0/tests/models_tests/serializable_model_user_test.py +54 -0
  26. boto3_assist-0.10.0/src/boto3_assist/version.py +0 -1
  27. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/.env.docker +0 -0
  28. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/.env.docker.001 +0 -0
  29. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/.env.docker.nosql.workbench +0 -0
  30. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/.env.unittest +0 -0
  31. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/.gitignore +0 -0
  32. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/.vscode/launch.json +0 -0
  33. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/.vscode/tasks.json +0 -0
  34. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/LICENSE-EXPLAINED.txt +0 -0
  35. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/LICENSE.txt +0 -0
  36. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/aws_regions_with_status.csv +0 -0
  37. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/aws_regions_with_status.json +0 -0
  38. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/devops/build.py +0 -0
  39. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/devops/readme.md +0 -0
  40. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/__init__.py +0 -0
  41. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/cloudwatch/log_report.py +0 -0
  42. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/models/order_item_model.py +0 -0
  43. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/models/order_model.py +0 -0
  44. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/models/product_model.py +0 -0
  45. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/models/user_model.py +0 -0
  46. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/models/user_post_model.py +0 -0
  47. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/order_example/main.py +0 -0
  48. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/order_example/products.json +0 -0
  49. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/services/order_item_service.py +0 -0
  50. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/services/order_service.py +0 -0
  51. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/services/product_service.py +0 -0
  52. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/services/table_service.py +0 -0
  53. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/services/user_post_service.py +0 -0
  54. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/services/user_service.py +0 -0
  55. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/services/user_service_client_example.py +0 -0
  56. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/services/user_service_resource_example.py +0 -0
  57. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/dynamodb/user_post_example/main.py +0 -0
  58. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/examples/ec2/regions_report.py +0 -0
  59. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/module-headers.txt +0 -0
  60. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/mypy.ini +0 -0
  61. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/requirements.txt +0 -0
  62. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/run-checks.sh +0 -0
  63. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/run_unit_tests.sh +0 -0
  64. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/__init__.py +0 -0
  65. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/aws_lambda/event_info.py +0 -0
  66. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/aws_lambda/mock_context.py +0 -0
  67. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/boto3session.py +0 -0
  68. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/cloudwatch/cloudwatch_connection.py +0 -0
  69. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/cloudwatch/cloudwatch_log_connection.py +0 -0
  70. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/cloudwatch/cloudwatch_logs.py +0 -0
  71. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/cloudwatch/cloudwatch_query.py +0 -0
  72. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/cognito/cognito_authorizer.py +0 -0
  73. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/cognito/cognito_connection.py +0 -0
  74. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/cognito/jwks_cache.py +0 -0
  75. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/cognito/user.py +0 -0
  76. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/connection.py +0 -0
  77. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/connection_tracker.py +0 -0
  78. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb.py +0 -0
  79. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_connection.py +0 -0
  80. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_helpers.py +0 -0
  81. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_importer.py +0 -0
  82. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_index.py +0 -0
  83. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_iservice.py +0 -0
  84. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_key.py +0 -0
  85. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_model_base_interfaces.py +0 -0
  86. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_reindexer.py +0 -0
  87. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.py +0 -0
  88. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.txt +0 -0
  89. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/readme.md +0 -0
  90. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/troubleshooting.md +0 -0
  91. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/ec2/ec2_connection.py +0 -0
  92. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/environment_services/__init__.py +0 -0
  93. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/environment_services/environment_loader.py +0 -0
  94. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/environment_services/environment_variables.py +0 -0
  95. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/errors/custom_exceptions.py +0 -0
  96. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/http_status_codes.py +0 -0
  97. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/models/serializable_model.py +0 -0
  98. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/s3/s3.py +0 -0
  99. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/s3/s3_bucket.py +0 -0
  100. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/s3/s3_connection.py +0 -0
  101. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/securityhub/securityhub_connection.py +0 -0
  102. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/ssm/connection.py +0 -0
  103. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/ssm/parameter_store/parameter_store.py +0 -0
  104. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/utilities/datetime_utility.py +0 -0
  105. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/utilities/dictionary_utility.py +0 -0
  106. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/utilities/file_operations.py +0 -0
  107. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/utilities/http_utility.py +0 -0
  108. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/utilities/logging_utility.py +0 -0
  109. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/src/boto3_assist/utilities/numbers_utility.py +0 -0
  110. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/__init__.py +0 -0
  111. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/__top/__init__.py +0 -0
  112. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/__init__.py +0 -0
  113. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/cms/base.py +0 -0
  114. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/simple_model.py +0 -0
  115. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/user_model.py +0 -0
  116. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/user_required_fields_model.py +0 -0
  117. {boto3_assist-0.10.0/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dynamodb_reindex_test.py +0 -0
  118. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/examples_test/__init__.py +0 -0
  119. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/examples_test/user_service_test.py +0 -0
  120. {boto3_assist-0.10.0/tests/lambda → boto3_assist-0.11.0/tests/lambda_tests}/__init__.py +0 -0
  121. {boto3_assist-0.10.0/tests/lambda → boto3_assist-0.11.0/tests/lambda_tests}/event_info_test.py +0 -0
  122. {boto3_assist-0.10.0/tests/models → boto3_assist-0.11.0/tests/models_tests}/__init__.py +0 -0
  123. {boto3_assist-0.10.0/tests/models → boto3_assist-0.11.0/tests/models_tests}/serializable_model_wide_test.py +0 -0
  124. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/parameter_store/__init__.py +0 -0
  125. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/parameter_store/parameter_store_test.py +0 -0
  126. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/s3/__init__.py +0 -0
  127. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/s3/files/test.txt +0 -0
  128. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/s3/s3_event_data_test.py +0 -0
  129. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/s3/s3_file_delete_test.py +0 -0
  130. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/s3/s3_file_upload_test.py +0 -0
  131. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/utilities/__init__.py +0 -0
  132. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/utilities/serialization_utility_test.py +0 -0
  133. {boto3_assist-0.10.0 → boto3_assist-0.11.0}/tests/utilities/string_utility_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
- "python.testing.pytestEnabled": false,
3
- "python.testing.unittestEnabled": true,
2
+ "python.testing.pytestEnabled": true,
3
+ "python.testing.unittestEnabled": false,
4
4
  "python.testing.unittestArgs": [
5
5
  "-v",
6
6
  "-s",
@@ -24,7 +24,7 @@
24
24
  "[python]": {
25
25
 
26
26
  "editor.formatOnSave": true,
27
- "editor.defaultFormatter": "charliermarsh.ruff",
27
+ "editor.defaultFormatter": "ms-python.black-formatter",
28
28
  },
29
29
 
30
30
  }
@@ -1,13 +1,16 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boto3_assist
3
- Version: 0.10.0
3
+ Version: 0.11.0
4
4
  Summary: Additional boto3 wrappers to make your life a little easier
5
5
  Author-email: Eric Wilson <boto3-assist@geekcafe.com>
6
6
  License-File: LICENSE-EXPLAINED.txt
7
7
  License-File: LICENSE.txt
8
- Classifier: License :: Other/Proprietary License
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: License :: OSI Approved :: MIT License
9
10
  Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python
10
12
  Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Software Development
11
14
  Requires-Python: >=3.10
12
15
  Requires-Dist: aws-lambda-powertools
13
16
  Requires-Dist: aws-xray-sdk
@@ -23,6 +26,10 @@ Description-Content-Type: text/markdown
23
26
 
24
27
  # boto3 assist
25
28
 
29
+ [![PyPI version](https://img.shields.io/pypi/v/boto3-assist.svg)](https://pypi.org/project/boto3-assist/)
30
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
31
+ [![Downloads](https://static.pepy.tech/badge/boto3-assist)](https://pepy.tech/project/boto3-assist)
32
+
26
33
  This is in beta and subject to changes before it's initial 1.0.0 release
27
34
 
28
35
  This libary was created to make life a little easier when using boto3.
@@ -1,5 +1,9 @@
1
1
  # boto3 assist
2
2
 
3
+ [![PyPI version](https://img.shields.io/pypi/v/boto3-assist.svg)](https://pypi.org/project/boto3-assist/)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Downloads](https://static.pepy.tech/badge/boto3-assist)](https://pepy.tech/project/boto3-assist)
6
+
3
7
  This is in beta and subject to changes before it's initial 1.0.0 release
4
8
 
5
9
  This libary was created to make life a little easier when using boto3.
@@ -11,7 +11,7 @@ testpaths = ["tests"]
11
11
 
12
12
  [project]
13
13
  name = "boto3_assist"
14
- version = "0.10.0"
14
+ version = "0.11.0"
15
15
 
16
16
  authors = [
17
17
  { name="Eric Wilson", email="boto3-assist@geekcafe.com" }
@@ -21,8 +21,11 @@ readme = "README.md"
21
21
  requires-python = ">=3.10"
22
22
  classifiers = [
23
23
  "Programming Language :: Python :: 3",
24
- "License :: Other/Proprietary License",
24
+ "License :: OSI Approved :: MIT License",
25
+ "Development Status :: 4 - Beta",
25
26
  "Operating System :: OS Independent",
27
+ "Programming Language :: Python",
28
+ "Topic :: Software Development"
26
29
  ]
27
30
 
28
31
  dependencies = [
@@ -19,4 +19,5 @@ pkginfo # occasionally we need to upgrade this or we can get upload errors when
19
19
  # the error may look like the following
20
20
  # ERROR InvalidDistribution: Metadata is missing required fields: Name, Version.
21
21
  # Make sure the distribution includes the files where those fields are specified, and is using a supported
22
- # Metadata-Version: 1.0, 1.1, 1.2, 2.0, 2.1, 2.2, 2.3.
22
+ # Metadata-Version: 1.0, 1.1, 1.2, 2.0, 2.1, 2.2, 2.3.
23
+ pytest
@@ -14,4 +14,4 @@ class CloudWatchConnectionTracker(ConnectionTracker):
14
14
  """
15
15
 
16
16
  def __init__(self) -> None:
17
- super().__init__("CloudWatch")
17
+ super().__init__()
@@ -5,7 +5,7 @@ MIT License. See Project Root for the license information.
5
5
  """
6
6
 
7
7
  import time
8
- from typing import List, Dict, Any, Optional
8
+ from typing import List, Dict, Any, Optional, Literal
9
9
 
10
10
 
11
11
  from aws_lambda_powertools import Logger
@@ -130,7 +130,7 @@ class CognitoUtility(CognitoConnection):
130
130
  is_permanent=True,
131
131
  )
132
132
 
133
- return response
133
+ return dict(response)
134
134
 
135
135
  except self.client.exceptions.UsernameExistsException as e:
136
136
  logger.error(f"Error: {e.response['Error']['Message']}")
@@ -185,7 +185,7 @@ class CognitoUtility(CognitoConnection):
185
185
  UserPoolId=user_pool_id, Username=user_name
186
186
  )
187
187
 
188
- return response
188
+ return dict(response)
189
189
 
190
190
  def admin_enable_user(
191
191
  self, user_name: str, user_pool_id: str, reset_password: bool = True
@@ -271,7 +271,7 @@ class CognitoUtility(CognitoConnection):
271
271
  logger.debug(
272
272
  f"User {email} created successfully. Confirmation code sent to {email}."
273
273
  )
274
- return response
274
+ return dict(response)
275
275
 
276
276
  except self.client.exceptions.UsernameExistsException as e:
277
277
  logger.error(f"Error: {e.response['Error']['Message']}")
@@ -324,11 +324,11 @@ class CognitoUtility(CognitoConnection):
324
324
  user_pool_id,
325
325
  client_name,
326
326
  id_token_time_out=60,
327
- id_token_units="minutes",
327
+ id_token_units: Literal["days", "hours", "minutes", "seconds"] = "minutes",
328
328
  access_token_time_out=60,
329
- access_token_units="minutes",
329
+ access_token_units: Literal["days", "hours", "minutes", "seconds"] = "minutes",
330
330
  refresh_token_time_out=60,
331
- refresh_token_units="minutes",
331
+ refresh_token_units: Literal["days", "hours", "minutes", "seconds"] = "minutes",
332
332
  ) -> dict:
333
333
  # valid units: 'seconds'|'minutes'|'hours'|'days'
334
334
 
@@ -340,9 +340,9 @@ class CognitoUtility(CognitoConnection):
340
340
  AccessTokenValidity=access_token_time_out,
341
341
  IdTokenValidity=id_token_time_out,
342
342
  TokenValidityUnits={
343
- "AccessToken": f"{access_token_units}",
344
- "IdToken": f"{id_token_units}",
345
- "RefreshToken": f"{refresh_token_units}",
343
+ "AccessToken": access_token_units,
344
+ "IdToken": id_token_units,
345
+ "RefreshToken": refresh_token_units,
346
346
  },
347
347
  # ReadAttributes=[
348
348
  # 'string',
@@ -381,18 +381,18 @@ class CognitoUtility(CognitoConnection):
381
381
  # AuthSessionValidity=123
382
382
  )
383
383
 
384
- return response
384
+ return dict(response)
385
385
 
386
386
  def search_cognito(self, email: str, user_pool_id: str) -> dict:
387
387
  """Search cognito for an existing user"""
388
388
 
389
- email = self.__format_email(email=email)
389
+ email = self.__format_email(email=email) or ""
390
390
  filter_string = f'email = "{email}"'
391
391
 
392
392
  # Call the admin_list_users method with the filter
393
393
  response = self.client.list_users(UserPoolId=user_pool_id, Filter=filter_string)
394
394
 
395
- return response
395
+ return dict(response)
396
396
 
397
397
  def __set_user_attributes(self, *, user: CognitoUser) -> List[dict]:
398
398
  """
@@ -249,6 +249,7 @@ class DynamoDBModelBase(SerializableModel):
249
249
  """
250
250
 
251
251
  value = DatetimeUtility.to_datetime_utc(value)
252
+ return value
252
253
 
253
254
 
254
255
  class DynamoDBSerializer:
@@ -15,37 +15,37 @@ class EventData:
15
15
  self.__event = event
16
16
 
17
17
  @property
18
- def version(self) -> str:
18
+ def version(self) -> str | None:
19
19
  """Event Version"""
20
20
  return self.__event.get("version")
21
21
 
22
22
  @property
23
- def id(self) -> str:
23
+ def id(self) -> str | None:
24
24
  """Event Id"""
25
25
  return self.__event.get("id")
26
26
 
27
27
  @property
28
- def detail_type(self) -> str:
28
+ def detail_type(self) -> str | None:
29
29
  """Event Detail Type"""
30
30
  return self.__event.get("detail-type")
31
31
 
32
32
  @property
33
- def source(self) -> str:
33
+ def source(self) -> str | None:
34
34
  """Event Source"""
35
35
  return self.__event.get("source")
36
36
 
37
37
  @property
38
- def account(self) -> str:
38
+ def account(self) -> str | None:
39
39
  """Event Account"""
40
40
  return self.__event.get("account")
41
41
 
42
42
  @property
43
- def time(self) -> str:
43
+ def time(self) -> str | None:
44
44
  """Event Time"""
45
45
  return self.__event.get("time")
46
46
 
47
47
  @property
48
- def region(self) -> str:
48
+ def region(self) -> str | None:
49
49
  """Event Region"""
50
50
  return self.__event.get("region")
51
51
 
@@ -217,7 +217,7 @@ class S3Object:
217
217
  )
218
218
  try:
219
219
  # convert if necessary
220
- file_obj: bytes = (
220
+ file_obj = (
221
221
  file_obj.encode("utf-8") if isinstance(file_obj, str) else file_obj
222
222
  )
223
223
  self.connection.client.upload_fileobj(
@@ -658,7 +658,7 @@ class S3Object:
658
658
  Key=destination_key,
659
659
  )
660
660
 
661
- return response
661
+ return dict(response)
662
662
 
663
663
  def move(
664
664
  self,
@@ -5,7 +5,7 @@ MIT License. See Project Root for the license information.
5
5
  """
6
6
 
7
7
  import os
8
- from typing import Optional
8
+ from typing import Optional, Literal
9
9
 
10
10
  from aws_lambda_powertools import Logger
11
11
 
@@ -20,7 +20,7 @@ class SecurityHub(SecurityHubConnection):
20
20
  def update_findings_status(
21
21
  self,
22
22
  region_name: str,
23
- workflow_status: str,
23
+ workflow_status: Literal["NEW", "NOTIFIED", "RESOLVED", "SUPPRESSED"],
24
24
  note_text: Optional[str] = None,
25
25
  updated_by: Optional[str] = None,
26
26
  ):
@@ -148,9 +148,11 @@ class JsonConversions:
148
148
  elif isinstance(data, list):
149
149
  # For lists, if deep conversion is enabled, process each element.
150
150
  return [
151
- JsonConversions._convert_keys(item, convert_func, deep)
152
- if deep
153
- else item
151
+ (
152
+ JsonConversions._convert_keys(item, convert_func, deep)
153
+ if deep
154
+ else item
155
+ )
154
156
  for item in data
155
157
  ]
156
158
  else:
@@ -377,7 +379,10 @@ class Serialization:
377
379
  setattr(target, "__actively_serializing_data__", True)
378
380
 
379
381
  for key, value in source.items():
380
- if Serialization.has_attribute(target, key):
382
+ if isinstance(target, dict):
383
+ # our target is a dictionary, so we need to handle this differently
384
+ target[key] = value
385
+ elif Serialization.has_attribute(target, key):
381
386
  attr = getattr(target, key)
382
387
  expected_type = type(attr)
383
388
 
@@ -313,6 +313,7 @@ class StringUtility:
313
313
  return True
314
314
  if value in ("false", "0", "f", "n", "no"):
315
315
  return False
316
+ raise ValueError(f"Invalid boolean value: {value}")
316
317
  elif isinstance(value, int):
317
318
  return bool(value)
318
319
  elif value is None:
@@ -0,0 +1 @@
1
+ __version__ = '0.11.0'
@@ -7,7 +7,7 @@ MIT License. See Project Root for the license information.
7
7
  import datetime as dt
8
8
  from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex, DynamoDBKey
9
9
  from boto3_assist.utilities.string_utility import StringUtility
10
- from tests.dynamodb.models.cms.base import BaseCMSDBModel
10
+ from tests.dynamodb_tests.models.cms.base import BaseCMSDBModel
11
11
 
12
12
 
13
13
  class ContentBlock(BaseCMSDBModel):
@@ -7,7 +7,7 @@ MIT License. See Project Root for the license information.
7
7
  from typing import List, Dict, Any
8
8
  import datetime as dt
9
9
  from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex, DynamoDBKey
10
- from tests.dynamodb.dbmodels.cms.base import BaseCMSDBModel
10
+ from tests.dynamodb_tests.dbmodels.cms.base import BaseCMSDBModel
11
11
 
12
12
 
13
13
  class Page(BaseCMSDBModel):
@@ -6,7 +6,7 @@ MIT License. See Project Root for the license information.
6
6
 
7
7
  from typing import List
8
8
  from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex, DynamoDBKey
9
- from tests.dynamodb.models.cms.base import BaseCMSDBModel
9
+ from tests.dynamodb_tests.models.cms.base import BaseCMSDBModel
10
10
 
11
11
 
12
12
  class Template(BaseCMSDBModel):
@@ -9,7 +9,7 @@ from typing import Dict, List
9
9
 
10
10
  from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex
11
11
  from boto3_assist.dynamodb.dynamodb_key import DynamoDBKey
12
- from tests.dynamodb.dbmodels.user_model import User
12
+ from tests.dynamodb_tests.dbmodels.user_model import User
13
13
 
14
14
 
15
15
  class DynamoDBModelUnitTest(unittest.TestCase):
@@ -7,8 +7,8 @@ MIT License. See Project Root for the license information.
7
7
  import unittest
8
8
 
9
9
 
10
- from tests.dynamodb.dbmodels.user_model import User
11
- from tests.dynamodb.dbmodels.simple_model import Simple
10
+ from tests.dynamodb_tests.dbmodels.user_model import User
11
+ from tests.dynamodb_tests.dbmodels.simple_model import Simple
12
12
 
13
13
 
14
14
  class DynamoDBModeProjectionlUnitTest(unittest.TestCase):
@@ -7,8 +7,8 @@ MIT License. See Project Root for the license information.
7
7
  import unittest
8
8
 
9
9
 
10
- from tests.dynamodb.dbmodels.user_model import User
11
- from tests.dynamodb.dbmodels.user_required_fields_model import User as User2
10
+ from tests.dynamodb_tests.dbmodels.user_model import User
11
+ from tests.dynamodb_tests.dbmodels.user_required_fields_model import User as User2
12
12
 
13
13
 
14
14
  class DynamoDBModelSerializationUnitTest(unittest.TestCase):
@@ -12,7 +12,7 @@ from mypy_boto3_dynamodb import DynamoDBClient
12
12
 
13
13
  from boto3_assist.dynamodb.dynamodb import DynamoDB
14
14
  from boto3_assist.environment_services.environment_loader import EnvironmentLoader
15
- from tests.dynamodb.dbmodels.cms.page import Page
15
+ from tests.dynamodb_tests.dbmodels.cms.page import Page
16
16
 
17
17
 
18
18
  @moto.mock_aws
@@ -146,9 +146,7 @@ class DynamoDBSortinglUnitTest(unittest.TestCase):
146
146
  "KeyType": "RANGE",
147
147
  }, # Sort key for GSI
148
148
  ],
149
- "Projection": {
150
- "ProjectionType": "ALL" # Project all attributes
151
- },
149
+ "Projection": {"ProjectionType": "ALL"}, # Project all attributes
152
150
  }
153
151
  ],
154
152
  BillingMode="PAY_PER_REQUEST",
@@ -0,0 +1,26 @@
1
+
2
+ """
3
+ Geek Cafe, LLC
4
+ Maintainers: Eric Wilson
5
+ MIT License. See Project Root for the license information.
6
+ """
7
+
8
+ from typing import List
9
+ from boto3_assist.models.serializable_model import SerializableModel
10
+
11
+ class Person(SerializableModel):
12
+ """A model that inherits the serializable"""
13
+
14
+ def __init__(self, name: str = "", age: int = 0, active: bool = False):
15
+ self.name = name
16
+ self.age = age
17
+ self.active = active
18
+ self.__pets: List[str] = []
19
+
20
+ @property
21
+ def pets(self) -> List[str]:
22
+ return self.__pets
23
+
24
+ @pets.setter
25
+ def pets(self, value: List[str]):
26
+ self.__pets = value
@@ -0,0 +1,66 @@
1
+ """
2
+ Geek Cafe, LLC
3
+ Maintainers: Eric Wilson
4
+ MIT License. See Project Root for the license information.
5
+ """
6
+
7
+ from typing import Dict, Any
8
+ from boto3_assist.models.serializable_model import SerializableModel
9
+
10
+
11
+ class User(SerializableModel):
12
+ """A model that inherits the serializable"""
13
+
14
+ def __init__(self):
15
+ self.__first_name: str | None = None
16
+ self.__last_name: str | None = None
17
+ self.__email: str | None = None
18
+ self.__meta_data: Dict[str, Any] = {}
19
+ self.settings: Dict[str, Any] = {}
20
+
21
+ @property
22
+ def first_name(self) -> str | None:
23
+ """The first name of the user"""
24
+ if self.__first_name is None:
25
+ return None
26
+ return self.__first_name
27
+
28
+ @first_name.setter
29
+ def first_name(self, value: str | None):
30
+ self.__first_name = value
31
+
32
+ @property
33
+ def last_name(self) -> str | None:
34
+ """The last name of the user"""
35
+ if self.__last_name is None:
36
+ return None
37
+ return self.__last_name
38
+
39
+ @last_name.setter
40
+ def last_name(self, value: str | None):
41
+ self.__last_name = value
42
+
43
+ @property
44
+ def email(self) -> str | None:
45
+ """The email address of the user"""
46
+ if self.__email is None:
47
+ return None
48
+ return self.__email
49
+
50
+ @email.setter
51
+ def email(self, value: str | None):
52
+ self.__email = value
53
+
54
+ @property
55
+ def meta_data(self) -> Dict[str, Any]:
56
+ """The last name of the user"""
57
+ if self.__meta_data is None:
58
+ return {}
59
+ return self.__meta_data
60
+
61
+ @meta_data.setter
62
+ def meta_data(self, value: Dict[str, Any] | None):
63
+ if value is None:
64
+ self.__meta_data = {}
65
+ return
66
+ self.__meta_data = value
@@ -7,24 +7,9 @@ MIT License. See Project Root for the license information.
7
7
  import unittest
8
8
  from typing import Dict, List
9
9
  from boto3_assist.models.serializable_model import SerializableModel
10
+ from tests.models_tests.models.person import Person
10
11
 
11
12
 
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
- self.__pets: List[str] = []
20
-
21
- @property
22
- def pets(self) -> List[str]:
23
- return self.__pets
24
-
25
- @pets.setter
26
- def pets(self, value: List[str]):
27
- self.__pets = value
28
13
 
29
14
 
30
15
  class TestSerializableModel(unittest.TestCase):
@@ -42,7 +27,7 @@ class TestSerializableModel(unittest.TestCase):
42
27
  """
43
28
  Test mapping a valid dictionary to an object instance.
44
29
  """
45
- result = ExampleModel().map(self.source_dict)
30
+ result = Person().map(self.source_dict)
46
31
 
47
32
  self.assertEqual(result.name, "John Doe")
48
33
  self.assertEqual(result.age, 30)
@@ -54,7 +39,7 @@ class TestSerializableModel(unittest.TestCase):
54
39
  Test mapping a dictionary with partial data.
55
40
  """
56
41
  partial_dict = {"name": "Jane Doe"}
57
- result = ExampleModel().map(partial_dict)
42
+ result = Person().map(partial_dict)
58
43
 
59
44
  self.assertEqual(result.name, "Jane Doe")
60
45
  self.assertEqual(result.age, 0) # Default value
@@ -65,7 +50,7 @@ class TestSerializableModel(unittest.TestCase):
65
50
  Test mapping an empty dictionary.
66
51
  """
67
52
  empty_dict = {}
68
- result = ExampleModel().map(empty_dict)
53
+ result = Person().map(empty_dict)
69
54
 
70
55
  self.assertEqual(result.name, "") # Default value
71
56
  self.assertEqual(result.age, 0) # Default value
@@ -78,7 +63,7 @@ class TestSerializableModel(unittest.TestCase):
78
63
  invalid_dict = {"name": 123, "age": "thirty", "active": "yes"}
79
64
 
80
65
  with self.assertRaises(ValueError):
81
- ExampleModel().map(invalid_dict, coerce=False)
66
+ Person().map(invalid_dict, coerce=False)
82
67
 
83
68
  def test_map_invalid_data_coerce_with_failure(self):
84
69
  """
@@ -86,7 +71,7 @@ class TestSerializableModel(unittest.TestCase):
86
71
  """
87
72
  invalid_dict = {"name": 123, "age": "thirty", "active": "yes"}
88
73
 
89
- result = ExampleModel().map(invalid_dict)
74
+ result = Person().map(invalid_dict)
90
75
 
91
76
  self.assertEqual(result.name, "123")
92
77
  # currently we're allowing this to happen
@@ -99,7 +84,7 @@ class TestSerializableModel(unittest.TestCase):
99
84
  """
100
85
  invalid_dict = {"name": 123, "age": 30, "active": "yes"}
101
86
 
102
- result = ExampleModel().map(invalid_dict)
87
+ result = Person().map(invalid_dict)
103
88
 
104
89
  self.assertEqual(result.name, "123")
105
90
  self.assertEqual(result.age, 30)
@@ -109,7 +94,7 @@ class TestSerializableModel(unittest.TestCase):
109
94
  """
110
95
  Test mapping a dictionary with invalid data types.
111
96
  """
112
- model: ExampleModel = ExampleModel(name="Fred", age=25, active=True)
97
+ model: Person = Person(name="Fred", age=25, active=True)
113
98
  invalid_dict = {"age": 30}
114
99
 
115
100
  result = model.map(invalid_dict)
@@ -122,9 +107,9 @@ class TestSerializableModel(unittest.TestCase):
122
107
  """
123
108
  Test mapping from a non-dictionary source object.
124
109
  """
125
- source_object = ExampleModel(name="Alice", age=25, active=True)
110
+ source_object = Person(name="Alice", age=25, active=True)
126
111
 
127
- result = ExampleModel().map(source_object)
112
+ result = Person().map(source_object)
128
113
 
129
114
  self.assertEqual(result.name, "Alice")
130
115
  self.assertEqual(result.age, 25)
@@ -134,7 +119,7 @@ class TestSerializableModel(unittest.TestCase):
134
119
  """
135
120
  Test converting an object instance to a dictionary.
136
121
  """
137
- model = ExampleModel(name="Bob", age=35, active=False)
122
+ model = Person(name="Bob", age=35, active=False)
138
123
 
139
124
  result = model.to_dictionary()
140
125
 
@@ -0,0 +1,54 @@
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, List, Any
9
+ from boto3_assist.models.serializable_model import SerializableModel
10
+ from tests.models_tests.models.user import User
11
+
12
+
13
+ class TestSerializableModel(unittest.TestCase):
14
+ """Testing Serialzing Models"""
15
+
16
+ def setUp(self) -> None:
17
+ self.source_dict: Dict[str, Any] = {
18
+ "first_name": "John",
19
+ "last_name": "Doe",
20
+ "meta_data": {
21
+ "favorite_color": "blue",
22
+ "favorite_food": "pizza",
23
+ "favorite_movie": "The Matrix",
24
+ "favorite_book": "The Lord of the Rings",
25
+ "favorite_music": "Classic Rock",
26
+ "favorite_hobby": "reading",
27
+ "favorite_sport": "football",
28
+ "favorite_tv_show": "The Office",
29
+ "favorite_animal": "dog",
30
+ "favorite_place": "home",
31
+ "favorite_drink": "water",
32
+ },
33
+ "settings": {
34
+ "notifications": True,
35
+ "dark_mode": False,
36
+ "language": "en",
37
+ "timezone": "UTC",
38
+ },
39
+ }
40
+
41
+ def test_map_valid_data(self):
42
+ """
43
+ Test mapping a valid dictionary to an object instance.
44
+ """
45
+ result = User().map(self.source_dict)
46
+
47
+ self.assertEqual(result.first_name, "John")
48
+ self.assertEqual(result.last_name, "Doe")
49
+ self.assertEqual(len(result.meta_data), 11)
50
+ self.assertEqual(len(result.settings), 4)
51
+
52
+
53
+ if __name__ == "__main__":
54
+ unittest.main()
@@ -1 +0,0 @@
1
- __version__ = '0.10.0'
File without changes
File without changes
File without changes
File without changes