boto3-assist 0.21.0__tar.gz → 0.22.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.
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/.vscode/settings.json +2 -1
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/PKG-INFO +1 -1
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/pyproject.toml +1 -1
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb.py +46 -9
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_model_base_interfaces.py +2 -2
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/utilities/datetime_utility.py +8 -10
- boto3_assist-0.22.0/src/boto3_assist/version.py +1 -0
- boto3_assist-0.22.0/tests/unit/dynamodb_tests/dynamodb_fail_if_exists_test.py +61 -0
- boto3_assist-0.21.0/src/boto3_assist/version.py +0 -1
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/.env.docker +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/.env.docker.001 +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/.env.docker.nosql.workbench +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/.env.unittest +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/.gitignore +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/.vscode/launch.json +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/.vscode/tasks.json +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/LICENSE-EXPLAINED.txt +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/LICENSE.txt +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/README.md +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/aws_regions_with_status.csv +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/aws_regions_with_status.json +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/devops/build.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/devops/readme.md +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/cloudwatch/log_report.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/models/order_item_model.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/models/order_model.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/models/product_model.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/models/user_model.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/models/user_post_model.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/order_example/main.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/order_example/products.json +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/services/order_item_service.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/services/order_service.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/services/product_service.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/services/table_service.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/services/user_post_service.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/services/user_service.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/services/user_service_client_example.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/services/user_service_resource_example.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/user_post_example/main.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/ec2/regions_report.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/module-headers.txt +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/mypy.ini +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/requirements-dev.txt +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/requirements.txt +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/run-checks.sh +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/run_unit_tests.sh +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/aws_config.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/aws_lambda/event_info.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/aws_lambda/mock_context.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/boto3session.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cloudwatch/cloudwatch_connection.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cloudwatch/cloudwatch_connection_tracker.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cloudwatch/cloudwatch_log_connection.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cloudwatch/cloudwatch_logs.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cloudwatch/cloudwatch_query.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cognito/cognito_authorizer.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cognito/cognito_connection.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cognito/cognito_utility.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cognito/jwks_cache.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cognito/user.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/connection.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/connection_tracker.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_connection.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_helpers.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_importer.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_index.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_iservice.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_key.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_model_base.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_re_indexer.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_reindexer.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.txt +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/readme.md +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/troubleshooting.md +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/ec2/ec2_connection.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/environment_services/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/environment_services/environment_loader.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/environment_services/environment_variables.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/errors/custom_exceptions.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/http_status_codes.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/models/serializable_model.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/role_assumption_mixin.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/s3/s3.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/s3/s3_bucket.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/s3/s3_connection.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/s3/s3_event_data.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/s3/s3_object.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/securityhub/securityhub.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/securityhub/securityhub_connection.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/session_setup_mixin.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/ssm/connection.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/ssm/parameter_store/parameter_store.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/utilities/dictionary_utility.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/utilities/file_operations.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/utilities/http_utility.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/utilities/logging_utility.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/utilities/numbers_utility.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/utilities/serialization_utility.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/utilities/string_utility.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/integration/cross_account_connection_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/integration/tenant.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/integration/tenant_services.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/aws_config_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/common/db_test_helpers.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/cms/base.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/cms/content_block.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/cms/page.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/cms/template.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/simple_model.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/user_model.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/user_required_fields_model.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/dynamodb_model_base_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/dynamodb_model_projections_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/dynamodb_model_serializtion_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/dynamodb_moto_sorting_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/dynamodb_query_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/dynamodb_reindex_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/examples_test/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/examples_test/user_service_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/lambda_tests/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/lambda_tests/event_info_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/models_tests/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/models_tests/models/person.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/models_tests/models/user.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/models_tests/serializable_model_person_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/models_tests/serializable_model_user_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/models_tests/serializable_model_wide_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/parameter_store/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/parameter_store/parameter_store_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/s3/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/s3/files/test.txt +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/s3/s3_event_data_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/s3/s3_file_delete_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/s3/s3_file_upload_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/session_tests/test_boto3_session_manager.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/utilities/__init__.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/utilities/serialization_utility_test.py +0 -0
- {boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/utilities/string_utility_test.py +0 -0
|
@@ -6,6 +6,8 @@ MIT License. See Project Root for the license information.
|
|
|
6
6
|
|
|
7
7
|
import os
|
|
8
8
|
from typing import List, Optional, overload, Dict, Any
|
|
9
|
+
from botocore.exceptions import ClientError
|
|
10
|
+
from boto3.dynamodb.conditions import Attr
|
|
9
11
|
|
|
10
12
|
from aws_lambda_powertools import Logger
|
|
11
13
|
from boto3.dynamodb.conditions import (
|
|
@@ -65,17 +67,22 @@ class DynamoDB(DynamoDBConnection):
|
|
|
65
67
|
item: dict | DynamoDBModelBase,
|
|
66
68
|
table_name: str,
|
|
67
69
|
source: Optional[str] = None,
|
|
70
|
+
fail_if_exists: bool = False,
|
|
68
71
|
) -> dict:
|
|
69
72
|
"""
|
|
70
73
|
Save an item to the database
|
|
71
74
|
Args:
|
|
72
|
-
item (dict): DynamoDB Dictionary Object or DynamoDBModelBase.
|
|
73
|
-
|
|
75
|
+
item (dict): DynamoDB Dictionary Object or DynamoDBModelBase.
|
|
76
|
+
Supports the "client" or "resource" syntax
|
|
74
77
|
table_name (str): The DynamoDb Table Name
|
|
75
78
|
source (str, optional): The source of the call, used for logging. Defaults to None.
|
|
79
|
+
fail_if_exists (bool, optional): Only allow it to insert once.
|
|
80
|
+
Fail if it already exits. This is useful for loggers, historical records,
|
|
81
|
+
tasks, etc. that should only be created once
|
|
76
82
|
|
|
77
83
|
Raises:
|
|
78
|
-
|
|
84
|
+
ClientError: Client specific errors
|
|
85
|
+
Exception: Any Error Raised
|
|
79
86
|
|
|
80
87
|
Returns:
|
|
81
88
|
dict: The Response from DynamoDB's put_item actions.
|
|
@@ -85,7 +92,7 @@ class DynamoDB(DynamoDBConnection):
|
|
|
85
92
|
|
|
86
93
|
try:
|
|
87
94
|
if not isinstance(item, dict):
|
|
88
|
-
#
|
|
95
|
+
# attempt to convert it
|
|
89
96
|
if not isinstance(item, DynamoDBModelBase):
|
|
90
97
|
raise RuntimeError(
|
|
91
98
|
f"Item is not a dictionary or DynamoDBModelBase. Type: {type(item).__name__}. "
|
|
@@ -106,19 +113,49 @@ class DynamoDB(DynamoDBConnection):
|
|
|
106
113
|
|
|
107
114
|
if isinstance(item, dict) and isinstance(next(iter(item.values())), dict):
|
|
108
115
|
# Use boto3.client syntax
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
116
|
+
# client API style
|
|
117
|
+
params = {
|
|
118
|
+
"TableName": table_name,
|
|
119
|
+
"Item": item,
|
|
120
|
+
}
|
|
121
|
+
if fail_if_exists:
|
|
122
|
+
# only insert if the item does *not* already exist
|
|
123
|
+
params["ConditionExpression"] = (
|
|
124
|
+
"attribute_not_exists(#pk) AND attribute_not_exists(#sk)"
|
|
125
|
+
)
|
|
126
|
+
params["ExpressionAttributeNames"] = {"#pk": "pk", "#sk": "sk"}
|
|
127
|
+
response = dict(self.dynamodb_client.put_item(**params))
|
|
128
|
+
|
|
112
129
|
else:
|
|
113
130
|
# Use boto3.resource syntax
|
|
114
131
|
table = self.dynamodb_resource.Table(table_name)
|
|
115
|
-
|
|
132
|
+
if fail_if_exists:
|
|
133
|
+
cond = Attr("pk").not_exists() & Attr("sk").not_exists()
|
|
134
|
+
response = dict(table.put_item(Item=item, ConditionExpression=cond))
|
|
135
|
+
else:
|
|
136
|
+
response = dict(table.put_item(Item=item))
|
|
137
|
+
# response = dict(table.put_item(Item=item)) # type: ignore[arg-type]
|
|
138
|
+
|
|
139
|
+
except ClientError as e:
|
|
140
|
+
if (
|
|
141
|
+
fail_if_exists
|
|
142
|
+
and e.response["Error"]["Code"] == "ConditionalCheckFailedException"
|
|
143
|
+
):
|
|
144
|
+
raise RuntimeError(
|
|
145
|
+
f"Item with pk={item['pk']} already exists in {table_name} "
|
|
146
|
+
f"and fail_if_exists was set to {fail_if_exists}"
|
|
147
|
+
) from e
|
|
148
|
+
|
|
149
|
+
logger.exception(
|
|
150
|
+
{"source": f"{source}", "metric_filter": "put_item", "error": str(e)}
|
|
151
|
+
)
|
|
152
|
+
raise
|
|
116
153
|
|
|
117
154
|
except Exception as e: # pylint: disable=w0718
|
|
118
155
|
logger.exception(
|
|
119
156
|
{"source": f"{source}", "metric_filter": "put_item", "error": str(e)}
|
|
120
157
|
)
|
|
121
|
-
raise
|
|
158
|
+
raise
|
|
122
159
|
|
|
123
160
|
return response
|
|
124
161
|
|
|
@@ -25,10 +25,10 @@ class HasKeys(Protocol):
|
|
|
25
25
|
"""Interface for classes that have primary and sort keys"""
|
|
26
26
|
|
|
27
27
|
def get_pk(self, index_name: str) -> Optional[str]:
|
|
28
|
-
"""
|
|
28
|
+
"""Interface to get_pk"""
|
|
29
29
|
|
|
30
30
|
def get_sk(self, index_name: str) -> Optional[str]:
|
|
31
|
-
"""
|
|
31
|
+
"""Interface to get_sk"""
|
|
32
32
|
|
|
33
33
|
def get_key(self, index_name: str) -> And | Equals:
|
|
34
34
|
"""Get the index name and key"""
|
|
@@ -12,7 +12,6 @@ from aws_lambda_powertools import Logger
|
|
|
12
12
|
from dateutil.relativedelta import relativedelta
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
logger = Logger()
|
|
17
16
|
|
|
18
17
|
_last_timestamp = None
|
|
@@ -43,11 +42,10 @@ class DatetimeUtility:
|
|
|
43
42
|
@staticmethod
|
|
44
43
|
def get_utc_now() -> datetime:
|
|
45
44
|
# datetime.utcnow()
|
|
46
|
-
# below is the
|
|
45
|
+
# below is the preferred over datetime.utcnow()
|
|
47
46
|
return datetime.now(timezone.utc)
|
|
48
47
|
|
|
49
48
|
@staticmethod
|
|
50
|
-
|
|
51
49
|
def string_to_date(string_date: str | datetime) -> datetime | None:
|
|
52
50
|
"""
|
|
53
51
|
Description: takes a string value and returns it as a datetime.
|
|
@@ -269,7 +267,7 @@ class DatetimeUtility:
|
|
|
269
267
|
months (int): the number of months
|
|
270
268
|
|
|
271
269
|
Returns:
|
|
272
|
-
datetime:
|
|
270
|
+
datetime: X Month(s) added to the input dt
|
|
273
271
|
"""
|
|
274
272
|
new_date = dt + relativedelta(months=+months)
|
|
275
273
|
new_date = new_date + relativedelta(microseconds=-1)
|
|
@@ -278,14 +276,14 @@ class DatetimeUtility:
|
|
|
278
276
|
|
|
279
277
|
@staticmethod
|
|
280
278
|
def add_days(dt: datetime, days: int = 1) -> datetime:
|
|
281
|
-
"""Add a
|
|
279
|
+
"""Add a day to the current date
|
|
282
280
|
|
|
283
281
|
Args:
|
|
284
282
|
dt (datetime): datetime
|
|
285
|
-
|
|
283
|
+
days (int): the number of days, use a negative number to subtract
|
|
286
284
|
|
|
287
285
|
Returns:
|
|
288
|
-
datetime:
|
|
286
|
+
datetime: X days added to the input dt
|
|
289
287
|
"""
|
|
290
288
|
new_date = dt + relativedelta(days=+days)
|
|
291
289
|
new_date = new_date + relativedelta(microseconds=-1)
|
|
@@ -314,7 +312,7 @@ class DatetimeUtility:
|
|
|
314
312
|
|
|
315
313
|
Args:
|
|
316
314
|
utc_datetime (datetime): datetime in utc
|
|
317
|
-
timezone (str): 'US/Eastern', 'US/
|
|
315
|
+
timezone (str): 'US/Eastern', 'US/Mountain', etc
|
|
318
316
|
|
|
319
317
|
Returns:
|
|
320
318
|
datetime: in the correct timezone
|
|
@@ -326,7 +324,7 @@ class DatetimeUtility:
|
|
|
326
324
|
|
|
327
325
|
@staticmethod
|
|
328
326
|
def get_timestamp(value: datetime | None | str) -> float:
|
|
329
|
-
"""Get a
|
|
327
|
+
"""Get a timestamp from a date or 0.0"""
|
|
330
328
|
if value is None:
|
|
331
329
|
return 0.0
|
|
332
330
|
if not isinstance(value, datetime):
|
|
@@ -339,7 +337,7 @@ class DatetimeUtility:
|
|
|
339
337
|
|
|
340
338
|
@staticmethod
|
|
341
339
|
def get_timestamp_or_none(value: datetime | None | str) -> float | None:
|
|
342
|
-
"""Get a
|
|
340
|
+
"""Get a timestamp from a date or None"""
|
|
343
341
|
if value is None:
|
|
344
342
|
return None
|
|
345
343
|
if not isinstance(value, datetime):
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.22.0'
|
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
import moto
|
|
9
|
+
|
|
10
|
+
from tests.unit.dynamodb_tests.db_models.user_model import User
|
|
11
|
+
from boto3_assist.environment_services.environment_loader import EnvironmentLoader
|
|
12
|
+
from boto3_assist.dynamodb.dynamodb import DynamoDB
|
|
13
|
+
from tests.unit.common.db_test_helpers import DbTestHelper
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@moto.mock_aws
|
|
17
|
+
class DbQueryTest(unittest.TestCase):
|
|
18
|
+
"Serialization Tests"
|
|
19
|
+
|
|
20
|
+
def __init__(self, methodName="runTest"):
|
|
21
|
+
super().__init__(methodName)
|
|
22
|
+
|
|
23
|
+
ev: EnvironmentLoader = EnvironmentLoader()
|
|
24
|
+
# NOTE: you need to make sure the the env file below exists or you will get an error
|
|
25
|
+
ev.load_environment_file(file_name=".env.unittest")
|
|
26
|
+
self.__table_name = "mock_test_table"
|
|
27
|
+
|
|
28
|
+
self.db: DynamoDB = DynamoDB()
|
|
29
|
+
|
|
30
|
+
def setUp(self):
|
|
31
|
+
# load our test environment file to make sure we override any default AWS Environment Vars setup
|
|
32
|
+
# we don't want to accidentally connect to live environments
|
|
33
|
+
# https://docs.getmoto.org/en/latest/docs/getting_started.html
|
|
34
|
+
|
|
35
|
+
self.db: DynamoDB = self.db or DynamoDB()
|
|
36
|
+
DbTestHelper().helper_create_mock_table(self.__table_name, self.db.client)
|
|
37
|
+
print("Setup Complete")
|
|
38
|
+
|
|
39
|
+
def test_fail_if_exists(self):
|
|
40
|
+
|
|
41
|
+
# create a few users
|
|
42
|
+
|
|
43
|
+
user_id: str = "123456789"
|
|
44
|
+
|
|
45
|
+
user = User(user_id)
|
|
46
|
+
response = self.db.save(table_name=self.__table_name, item=user)
|
|
47
|
+
|
|
48
|
+
self.assertEqual(response["ResponseMetadata"]["HTTPStatusCode"], 200)
|
|
49
|
+
|
|
50
|
+
# this will fail, fail_if_exists is set to true
|
|
51
|
+
self.assertRaises(
|
|
52
|
+
Exception,
|
|
53
|
+
self.db.save,
|
|
54
|
+
table_name=self.__table_name,
|
|
55
|
+
item=user,
|
|
56
|
+
fail_if_exists=True,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# this does not
|
|
60
|
+
response = self.db.save(table_name=self.__table_name, item=user)
|
|
61
|
+
self.assertEqual(response["ResponseMetadata"]["HTTPStatusCode"], 200)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.21.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
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/examples/dynamodb/services/order_item_service.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
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/cloudwatch/cloudwatch_connection.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/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
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_connection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_model_base.py
RENAMED
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_re_indexer.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.py
RENAMED
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/dynamodb/dynamodb_reserved_words.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/environment_services/__init__.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
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/securityhub/securityhub_connection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/ssm/parameter_store/parameter_store.py
RENAMED
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/utilities/dictionary_utility.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/src/boto3_assist/utilities/serialization_utility.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/integration/cross_account_connection_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/cms/content_block.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/cms/template.py
RENAMED
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/simple_model.py
RENAMED
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/db_models/user_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/dynamodb_model_base_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/dynamodb_moto_sorting_test.py
RENAMED
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/dynamodb_query_test.py
RENAMED
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/dynamodb_tests/dynamodb_reindex_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.21.0 → boto3_assist-0.22.0}/tests/unit/models_tests/serializable_model_user_test.py
RENAMED
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/models_tests/serializable_model_wide_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/parameter_store/parameter_store_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/session_tests/test_boto3_session_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
{boto3_assist-0.21.0 → boto3_assist-0.22.0}/tests/unit/utilities/serialization_utility_test.py
RENAMED
|
File without changes
|
|
File without changes
|