boto3-assist 0.9.5__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 (134) hide show
  1. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/.vscode/settings.json +3 -3
  2. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/PKG-INFO +25 -2
  3. boto3_assist-0.11.0/README.md +50 -0
  4. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/pyproject.toml +9 -2
  5. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/requirements-dev.txt +2 -1
  6. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/cloudwatch/cloudwatch_connection_tracker.py +1 -1
  7. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/cognito/cognito_utility.py +13 -13
  8. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb.py +5 -5
  9. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_helpers.py +4 -5
  10. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_model_base.py +1 -0
  11. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/s3/s3_event_data.py +7 -7
  12. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/s3/s3_object.py +2 -2
  13. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/securityhub/securityhub.py +2 -2
  14. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/utilities/datetime_utility.py +3 -3
  15. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/utilities/serialization_utility.py +9 -4
  16. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/utilities/string_utility.py +1 -0
  17. boto3_assist-0.11.0/src/boto3_assist/version.py +1 -0
  18. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/cms/content_block.py +1 -1
  19. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/cms/page.py +1 -1
  20. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/cms/template.py +1 -1
  21. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dynamodb_model_base_test.py +1 -1
  22. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dynamodb_model_projections_test.py +2 -2
  23. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dynamodb_model_serializtion_test.py +2 -2
  24. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dynamodb_moto_sorting_test.py +2 -4
  25. boto3_assist-0.11.0/tests/models_tests/models/person.py +26 -0
  26. boto3_assist-0.11.0/tests/models_tests/models/user.py +66 -0
  27. boto3_assist-0.9.5/tests/models/serializable_model_test.py → boto3_assist-0.11.0/tests/models_tests/serializable_model_person_test.py +11 -26
  28. boto3_assist-0.11.0/tests/models_tests/serializable_model_user_test.py +54 -0
  29. boto3_assist-0.9.5/README.md +0 -30
  30. boto3_assist-0.9.5/src/boto3_assist/version.py +0 -1
  31. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/.env.docker +0 -0
  32. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/.env.docker.001 +0 -0
  33. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/.env.docker.nosql.workbench +0 -0
  34. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/.env.unittest +0 -0
  35. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/.gitignore +0 -0
  36. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/.vscode/launch.json +0 -0
  37. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/.vscode/tasks.json +0 -0
  38. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/LICENSE-EXPLAINED.txt +0 -0
  39. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/LICENSE.txt +0 -0
  40. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/aws_regions_with_status.csv +0 -0
  41. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/aws_regions_with_status.json +0 -0
  42. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/devops/build.py +0 -0
  43. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/devops/readme.md +0 -0
  44. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/__init__.py +0 -0
  45. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/cloudwatch/log_report.py +0 -0
  46. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/models/order_item_model.py +0 -0
  47. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/models/order_model.py +0 -0
  48. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/models/product_model.py +0 -0
  49. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/models/user_model.py +0 -0
  50. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/models/user_post_model.py +0 -0
  51. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/order_example/main.py +0 -0
  52. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/order_example/products.json +0 -0
  53. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/services/order_item_service.py +0 -0
  54. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/services/order_service.py +0 -0
  55. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/services/product_service.py +0 -0
  56. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/services/table_service.py +0 -0
  57. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/services/user_post_service.py +0 -0
  58. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/services/user_service.py +0 -0
  59. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/services/user_service_client_example.py +0 -0
  60. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/services/user_service_resource_example.py +0 -0
  61. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/dynamodb/user_post_example/main.py +0 -0
  62. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/examples/ec2/regions_report.py +0 -0
  63. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/module-headers.txt +0 -0
  64. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/mypy.ini +0 -0
  65. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/requirements.txt +0 -0
  66. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/run-checks.sh +0 -0
  67. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/run_unit_tests.sh +0 -0
  68. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/__init__.py +0 -0
  69. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/aws_lambda/event_info.py +0 -0
  70. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/aws_lambda/mock_context.py +0 -0
  71. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/boto3session.py +0 -0
  72. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/cloudwatch/cloudwatch_connection.py +0 -0
  73. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/cloudwatch/cloudwatch_log_connection.py +0 -0
  74. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/cloudwatch/cloudwatch_logs.py +0 -0
  75. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/cloudwatch/cloudwatch_query.py +0 -0
  76. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/cognito/cognito_authorizer.py +0 -0
  77. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/cognito/cognito_connection.py +0 -0
  78. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/cognito/jwks_cache.py +0 -0
  79. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/cognito/user.py +0 -0
  80. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/connection.py +0 -0
  81. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/connection_tracker.py +0 -0
  82. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_connection.py +0 -0
  83. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_importer.py +0 -0
  84. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_index.py +0 -0
  85. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_iservice.py +0 -0
  86. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_key.py +0 -0
  87. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_model_base_interfaces.py +0 -0
  88. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_reindexer.py +0 -0
  89. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.py +0 -0
  90. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.txt +0 -0
  91. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/readme.md +0 -0
  92. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/dynamodb/troubleshooting.md +0 -0
  93. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/ec2/ec2_connection.py +0 -0
  94. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/environment_services/__init__.py +0 -0
  95. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/environment_services/environment_loader.py +0 -0
  96. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/environment_services/environment_variables.py +0 -0
  97. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/errors/custom_exceptions.py +0 -0
  98. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/http_status_codes.py +0 -0
  99. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/models/serializable_model.py +0 -0
  100. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/s3/s3.py +0 -0
  101. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/s3/s3_bucket.py +0 -0
  102. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/s3/s3_connection.py +0 -0
  103. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/securityhub/securityhub_connection.py +0 -0
  104. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/ssm/connection.py +0 -0
  105. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/ssm/parameter_store/parameter_store.py +0 -0
  106. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/utilities/dictionary_utility.py +0 -0
  107. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/utilities/file_operations.py +0 -0
  108. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/utilities/http_utility.py +0 -0
  109. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/utilities/logging_utility.py +0 -0
  110. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/src/boto3_assist/utilities/numbers_utility.py +0 -0
  111. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/__init__.py +0 -0
  112. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/__top/__init__.py +0 -0
  113. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/__init__.py +0 -0
  114. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/cms/base.py +0 -0
  115. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/simple_model.py +0 -0
  116. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/user_model.py +0 -0
  117. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dbmodels/user_required_fields_model.py +0 -0
  118. {boto3_assist-0.9.5/tests/dynamodb → boto3_assist-0.11.0/tests/dynamodb_tests}/dynamodb_reindex_test.py +0 -0
  119. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/examples_test/__init__.py +0 -0
  120. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/examples_test/user_service_test.py +0 -0
  121. {boto3_assist-0.9.5/tests/lambda → boto3_assist-0.11.0/tests/lambda_tests}/__init__.py +0 -0
  122. {boto3_assist-0.9.5/tests/lambda → boto3_assist-0.11.0/tests/lambda_tests}/event_info_test.py +0 -0
  123. {boto3_assist-0.9.5/tests/models → boto3_assist-0.11.0/tests/models_tests}/__init__.py +0 -0
  124. {boto3_assist-0.9.5/tests/models → boto3_assist-0.11.0/tests/models_tests}/serializable_model_wide_test.py +0 -0
  125. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/parameter_store/__init__.py +0 -0
  126. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/parameter_store/parameter_store_test.py +0 -0
  127. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/s3/__init__.py +0 -0
  128. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/s3/files/test.txt +0 -0
  129. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/s3/s3_event_data_test.py +0 -0
  130. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/s3/s3_file_delete_test.py +0 -0
  131. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/s3/s3_file_upload_test.py +0 -0
  132. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/utilities/__init__.py +0 -0
  133. {boto3_assist-0.9.5 → boto3_assist-0.11.0}/tests/utilities/serialization_utility_test.py +0 -0
  134. {boto3_assist-0.9.5 → 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.9.5
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.
@@ -51,3 +58,19 @@ pip install boto3-assist
51
58
 
52
59
  ```
53
60
 
61
+ ## Running Unit Tests
62
+ Several of our tests use a mocking library to simulate connections to S3, DynamoDB, etc. In order to use those tests, you will need to have a `.env.unittest` file at the root of this project (which our tests will attempt to locate and load).
63
+
64
+ For your convenince the `.evn.unittest` file has been added to this project. The values should not point to live AWS profiles, instead it should use the values added.
65
+
66
+ Since we also point to a profile, you should create the profile in the `~/.aws/config` file. The entry should look like the following:
67
+
68
+ ```toml
69
+ [profile moto-mock-tests]
70
+ region = us-east-1
71
+ output = json
72
+ aws_access_key_id = test
73
+ aws_secret_access_key = test
74
+
75
+ ```
76
+
@@ -0,0 +1,50 @@
1
+ # boto3 assist
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
+
7
+ This is in beta and subject to changes before it's initial 1.0.0 release
8
+
9
+ This libary was created to make life a little easier when using boto3.
10
+
11
+ Currently it supports:
12
+ - User Authentication / Session Mapping
13
+ - DynamoDB model mapping and key generation.
14
+
15
+
16
+ ## User Authentication / Session Mapping
17
+ Have you ever needed an easy way to load your sessions for a local, dev or production enviroment? Well this library
18
+ makes it a little easier by lazy loading your boto3 session so that tools like `python-dotenv` can be used to load your
19
+ environment vars first and then load your session.
20
+
21
+ ## DyamoDB model mapping and Key Generation
22
+ It's a light weight mapping tool to turn your python classes / object models to DynamoDB items that are ready
23
+ for saving. See the [examples](https://github.com/geekcafe/boto3-assist/tree/main/examples) directory in the repo for more information.
24
+
25
+
26
+ ```sh
27
+ python -m vevn .venv
28
+ source ./.venv/bin/activate
29
+
30
+ pip install --upgrade pip
31
+ pip install boto3-assist
32
+
33
+ ```
34
+
35
+ ## Running Unit Tests
36
+ Several of our tests use a mocking library to simulate connections to S3, DynamoDB, etc. In order to use those tests, you will need to have a `.env.unittest` file at the root of this project (which our tests will attempt to locate and load).
37
+
38
+ For your convenince the `.evn.unittest` file has been added to this project. The values should not point to live AWS profiles, instead it should use the values added.
39
+
40
+ Since we also point to a profile, you should create the profile in the `~/.aws/config` file. The entry should look like the following:
41
+
42
+ ```toml
43
+ [profile moto-mock-tests]
44
+ region = us-east-1
45
+ output = json
46
+ aws_access_key_id = test
47
+ aws_secret_access_key = test
48
+
49
+ ```
50
+
@@ -5,9 +5,13 @@ build-backend = "hatchling.build"
5
5
  [tool.hatch.build.targets.wheel]
6
6
  packages = ["src/boto3_assist"]
7
7
 
8
+ [tool.pytest.ini_options]
9
+ pythonpath = ["src"]
10
+ testpaths = ["tests"]
11
+
8
12
  [project]
9
13
  name = "boto3_assist"
10
- version = "0.9.5"
14
+ version = "0.11.0"
11
15
 
12
16
  authors = [
13
17
  { name="Eric Wilson", email="boto3-assist@geekcafe.com" }
@@ -17,8 +21,11 @@ readme = "README.md"
17
21
  requires-python = ">=3.10"
18
22
  classifiers = [
19
23
  "Programming Language :: Python :: 3",
20
- "License :: Other/Proprietary License",
24
+ "License :: OSI Approved :: MIT License",
25
+ "Development Status :: 4 - Beta",
21
26
  "Operating System :: OS Independent",
27
+ "Programming Language :: Python",
28
+ "Topic :: Software Development"
22
29
  ]
23
30
 
24
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
  """
@@ -7,7 +7,7 @@ MIT License. See Project Root for the license information.
7
7
  import os
8
8
  from typing import List, Optional, overload, Dict, Any
9
9
 
10
- from aws_lambda_powertools import Tracer, Logger
10
+ from aws_lambda_powertools import Logger
11
11
  from boto3.dynamodb.conditions import (
12
12
  Key,
13
13
  # And,
@@ -22,7 +22,7 @@ from boto3_assist.utilities.string_utility import StringUtility
22
22
 
23
23
 
24
24
  logger = Logger()
25
- tracer = Tracer()
25
+
26
26
 
27
27
 
28
28
  class DynamoDB(DynamoDBConnection):
@@ -55,7 +55,7 @@ class DynamoDB(DynamoDBConnection):
55
55
  )
56
56
  logger.setLevel(os.getenv("LOG_LEVEL", "INFO"))
57
57
 
58
- @tracer.capture_method
58
+
59
59
  def save(
60
60
  self,
61
61
  item: dict | DynamoDBModelBase,
@@ -169,7 +169,7 @@ class DynamoDB(DynamoDBConnection):
169
169
  call_type: str = "resource",
170
170
  ) -> Dict[str, Any]: ...
171
171
 
172
- @tracer.capture_method
172
+
173
173
  def get(
174
174
  self,
175
175
  key: Optional[dict] = None,
@@ -344,7 +344,7 @@ class DynamoDB(DynamoDBConnection):
344
344
  ) -> dict:
345
345
  pass
346
346
 
347
- @tracer.capture_method
347
+
348
348
  def delete(
349
349
  self,
350
350
  *,
@@ -7,11 +7,11 @@ MIT License. See Project Root for the license information.
7
7
  from typing import List, Any, Dict
8
8
 
9
9
  from boto3.dynamodb.conditions import ConditionBase, Key, And, Equals
10
- from aws_lambda_powertools import Tracer, Logger
10
+ from aws_lambda_powertools import Logger
11
11
  from boto3_assist.dynamodb.dynamodb_index import DynamoDBIndex
12
12
 
13
13
  logger = Logger()
14
- tracer = Tracer()
14
+
15
15
 
16
16
 
17
17
  class DynamoDBHelpers:
@@ -118,7 +118,7 @@ class DynamoDBHelpers:
118
118
  logger.error({"exception": str(e)})
119
119
  return "unknown"
120
120
 
121
- @tracer.capture_method(capture_response=False)
121
+
122
122
  def wrap_response(self, items, dynamodb_response: dict, diagnostics) -> dict:
123
123
  """A wrapper for response data"""
124
124
  last_key = dynamodb_response.get("LastEvaluatedKey", None)
@@ -135,8 +135,7 @@ class DynamoDBHelpers:
135
135
  }
136
136
 
137
137
  return response
138
-
139
- @tracer.capture_method(capture_response=False)
138
+
140
139
  def wrap_collection_response(self, collection: List[dict]) -> dict[str, List]:
141
140
  """
142
141
  Wraps Up Some usefull information when dealing with
@@ -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
  ):
@@ -8,11 +8,11 @@ import uuid
8
8
  from datetime import UTC, datetime, timedelta, timezone
9
9
  from typing import Any
10
10
  import pytz # type: ignore
11
- from aws_lambda_powertools import Tracer, Logger
11
+ from aws_lambda_powertools import Logger
12
12
  from dateutil.relativedelta import relativedelta
13
13
 
14
14
 
15
- tracer = Tracer()
15
+
16
16
  logger = Logger()
17
17
 
18
18
  _last_timestamp = None
@@ -47,7 +47,7 @@ class DatetimeUtility:
47
47
  return datetime.now(timezone.utc)
48
48
 
49
49
  @staticmethod
50
- @tracer.capture_method(capture_response=False)
50
+
51
51
  def string_to_date(string_date: str | datetime) -> datetime | None:
52
52
  """
53
53
  Description: takes a string value and returns it as a datetime.
@@ -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