boto3-assist 0.32.0__py3-none-any.whl
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/__init__.py +0 -0
- boto3_assist/aws_config.py +199 -0
- boto3_assist/aws_lambda/event_info.py +414 -0
- boto3_assist/aws_lambda/mock_context.py +5 -0
- boto3_assist/boto3session.py +87 -0
- boto3_assist/cloudwatch/cloudwatch_connection.py +84 -0
- boto3_assist/cloudwatch/cloudwatch_connection_tracker.py +17 -0
- boto3_assist/cloudwatch/cloudwatch_log_connection.py +62 -0
- boto3_assist/cloudwatch/cloudwatch_logs.py +39 -0
- boto3_assist/cloudwatch/cloudwatch_query.py +191 -0
- boto3_assist/cognito/cognito_authorizer.py +169 -0
- boto3_assist/cognito/cognito_connection.py +59 -0
- boto3_assist/cognito/cognito_utility.py +514 -0
- boto3_assist/cognito/jwks_cache.py +21 -0
- boto3_assist/cognito/user.py +27 -0
- boto3_assist/connection.py +146 -0
- boto3_assist/connection_tracker.py +120 -0
- boto3_assist/dynamodb/dynamodb.py +1206 -0
- boto3_assist/dynamodb/dynamodb_connection.py +113 -0
- boto3_assist/dynamodb/dynamodb_helpers.py +333 -0
- boto3_assist/dynamodb/dynamodb_importer.py +102 -0
- boto3_assist/dynamodb/dynamodb_index.py +507 -0
- boto3_assist/dynamodb/dynamodb_iservice.py +29 -0
- boto3_assist/dynamodb/dynamodb_key.py +130 -0
- boto3_assist/dynamodb/dynamodb_model_base.py +382 -0
- boto3_assist/dynamodb/dynamodb_model_base_interfaces.py +34 -0
- boto3_assist/dynamodb/dynamodb_re_indexer.py +165 -0
- boto3_assist/dynamodb/dynamodb_reindexer.py +165 -0
- boto3_assist/dynamodb/dynamodb_reserved_words.py +52 -0
- boto3_assist/dynamodb/dynamodb_reserved_words.txt +573 -0
- boto3_assist/dynamodb/readme.md +68 -0
- boto3_assist/dynamodb/troubleshooting.md +7 -0
- boto3_assist/ec2/ec2_connection.py +57 -0
- boto3_assist/environment_services/__init__.py +0 -0
- boto3_assist/environment_services/environment_loader.py +128 -0
- boto3_assist/environment_services/environment_variables.py +219 -0
- boto3_assist/erc/__init__.py +64 -0
- boto3_assist/erc/ecr_connection.py +57 -0
- boto3_assist/errors/custom_exceptions.py +46 -0
- boto3_assist/http_status_codes.py +80 -0
- boto3_assist/models/serializable_model.py +9 -0
- boto3_assist/role_assumption_mixin.py +38 -0
- boto3_assist/s3/s3.py +64 -0
- boto3_assist/s3/s3_bucket.py +67 -0
- boto3_assist/s3/s3_connection.py +76 -0
- boto3_assist/s3/s3_event_data.py +168 -0
- boto3_assist/s3/s3_object.py +695 -0
- boto3_assist/securityhub/securityhub.py +150 -0
- boto3_assist/securityhub/securityhub_connection.py +57 -0
- boto3_assist/session_setup_mixin.py +70 -0
- boto3_assist/ssm/connection.py +57 -0
- boto3_assist/ssm/parameter_store/parameter_store.py +116 -0
- boto3_assist/utilities/datetime_utility.py +349 -0
- boto3_assist/utilities/decimal_conversion_utility.py +140 -0
- boto3_assist/utilities/dictionary_utility.py +32 -0
- boto3_assist/utilities/file_operations.py +135 -0
- boto3_assist/utilities/http_utility.py +48 -0
- boto3_assist/utilities/logging_utility.py +0 -0
- boto3_assist/utilities/numbers_utility.py +329 -0
- boto3_assist/utilities/serialization_utility.py +664 -0
- boto3_assist/utilities/string_utility.py +337 -0
- boto3_assist/version.py +1 -0
- boto3_assist-0.32.0.dist-info/METADATA +76 -0
- boto3_assist-0.32.0.dist-info/RECORD +67 -0
- boto3_assist-0.32.0.dist-info/WHEEL +4 -0
- boto3_assist-0.32.0.dist-info/licenses/LICENSE-EXPLAINED.txt +11 -0
- boto3_assist-0.32.0.dist-info/licenses/LICENSE.txt +21 -0
boto3_assist/s3/s3.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
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 Optional, cast
|
|
8
|
+
|
|
9
|
+
from aws_lambda_powertools import Logger
|
|
10
|
+
|
|
11
|
+
from boto3_assist.s3.s3_connection import S3Connection
|
|
12
|
+
from boto3_assist.s3.s3_object import S3Object
|
|
13
|
+
from boto3_assist.s3.s3_bucket import S3Bucket
|
|
14
|
+
|
|
15
|
+
logger = Logger(child=True)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class S3(S3Connection):
|
|
19
|
+
"""Common S3 Actions"""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
*,
|
|
24
|
+
aws_profile: Optional[str] = None,
|
|
25
|
+
aws_region: Optional[str] = None,
|
|
26
|
+
aws_end_point_url: Optional[str] = None,
|
|
27
|
+
aws_access_key_id: Optional[str] = None,
|
|
28
|
+
aws_secret_access_key: Optional[str] = None,
|
|
29
|
+
) -> None:
|
|
30
|
+
"""_summary_
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
aws_profile (Optional[str], optional): _description_. Defaults to None.
|
|
34
|
+
aws_region (Optional[str], optional): _description_. Defaults to None.
|
|
35
|
+
aws_end_point_url (Optional[str], optional): _description_. Defaults to None.
|
|
36
|
+
aws_access_key_id (Optional[str], optional): _description_. Defaults to None.
|
|
37
|
+
aws_secret_access_key (Optional[str], optional): _description_. Defaults to None.
|
|
38
|
+
"""
|
|
39
|
+
super().__init__(
|
|
40
|
+
aws_profile=aws_profile,
|
|
41
|
+
aws_region=aws_region,
|
|
42
|
+
aws_end_point_url=aws_end_point_url,
|
|
43
|
+
aws_access_key_id=aws_access_key_id,
|
|
44
|
+
aws_secret_access_key=aws_secret_access_key,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
self.__s3_object: S3Object | None = None
|
|
48
|
+
self.__s3_bucket: S3Bucket | None = None
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def object(self) -> S3Object:
|
|
52
|
+
"""s3 object"""
|
|
53
|
+
if self.__s3_object is None:
|
|
54
|
+
connection = cast(S3Connection, self)
|
|
55
|
+
self.__s3_object = S3Object(connection)
|
|
56
|
+
return self.__s3_object
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def bucket(self) -> S3Bucket:
|
|
60
|
+
"""s3 bucket"""
|
|
61
|
+
if self.__s3_bucket is None:
|
|
62
|
+
connection = cast(S3Connection, self)
|
|
63
|
+
self.__s3_bucket = S3Bucket(connection)
|
|
64
|
+
return self.__s3_bucket
|
|
@@ -0,0 +1,67 @@
|
|
|
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 Any, Dict
|
|
8
|
+
|
|
9
|
+
from aws_lambda_powertools import Logger
|
|
10
|
+
from botocore.exceptions import ClientError
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
from boto3_assist.s3.s3_connection import S3Connection
|
|
14
|
+
|
|
15
|
+
logger = Logger(child=True)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class S3Bucket:
|
|
19
|
+
"""Common S3 Actions"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, connection: S3Connection):
|
|
22
|
+
self.connection = connection or S3Connection()
|
|
23
|
+
|
|
24
|
+
def create(self, *, bucket_name: str) -> Dict[str, Any]:
|
|
25
|
+
"""
|
|
26
|
+
Create an S3 bucket
|
|
27
|
+
:param bucket_name: Bucket to create
|
|
28
|
+
:return: True if bucket is created, else False
|
|
29
|
+
"""
|
|
30
|
+
try:
|
|
31
|
+
response = self.connection.client.create_bucket(Bucket=bucket_name)
|
|
32
|
+
logger.info(f"Bucket {bucket_name} created")
|
|
33
|
+
|
|
34
|
+
return dict(response)
|
|
35
|
+
except ClientError as e:
|
|
36
|
+
logger.exception(e)
|
|
37
|
+
raise e
|
|
38
|
+
|
|
39
|
+
def enable_versioning(self, *, bucket_name: str) -> None:
|
|
40
|
+
"""
|
|
41
|
+
Enable versioning on an S3 bucket
|
|
42
|
+
:param bucket_name: Bucket to enable versioning on
|
|
43
|
+
:return: None
|
|
44
|
+
"""
|
|
45
|
+
try:
|
|
46
|
+
self.connection.client.put_bucket_versioning(
|
|
47
|
+
Bucket=bucket_name, VersioningConfiguration={"Status": "Enabled"}
|
|
48
|
+
)
|
|
49
|
+
logger.info(f"Versioning enabled on bucket {bucket_name}")
|
|
50
|
+
except ClientError as e:
|
|
51
|
+
logger.exception(e)
|
|
52
|
+
raise e
|
|
53
|
+
|
|
54
|
+
def disable_versioning(self, *, bucket_name: str) -> None:
|
|
55
|
+
"""
|
|
56
|
+
Disable versioning on an S3 bucket
|
|
57
|
+
:param bucket_name: Bucket to disable versioning on
|
|
58
|
+
:return: None
|
|
59
|
+
"""
|
|
60
|
+
try:
|
|
61
|
+
self.connection.client.put_bucket_versioning(
|
|
62
|
+
Bucket=bucket_name, VersioningConfiguration={"Status": "Suspended"}
|
|
63
|
+
)
|
|
64
|
+
logger.info(f"Versioning disabled on bucket {bucket_name}")
|
|
65
|
+
except ClientError as e:
|
|
66
|
+
logger.exception(e)
|
|
67
|
+
raise e
|
|
@@ -0,0 +1,76 @@
|
|
|
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 Optional
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from aws_lambda_powertools import Logger
|
|
11
|
+
|
|
12
|
+
from boto3_assist.connection import Connection
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from mypy_boto3_s3 import S3Client, S3ServiceResource
|
|
16
|
+
else:
|
|
17
|
+
S3Client = object
|
|
18
|
+
S3ServiceResource = object
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
logger = Logger()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class S3Connection(Connection):
|
|
25
|
+
"""Connection"""
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
*,
|
|
30
|
+
aws_profile: Optional[str] = None,
|
|
31
|
+
aws_region: Optional[str] = None,
|
|
32
|
+
aws_end_point_url: Optional[str] = None,
|
|
33
|
+
aws_access_key_id: Optional[str] = None,
|
|
34
|
+
aws_secret_access_key: Optional[str] = None,
|
|
35
|
+
) -> None:
|
|
36
|
+
super().__init__(
|
|
37
|
+
service_name="s3",
|
|
38
|
+
aws_profile=aws_profile,
|
|
39
|
+
aws_region=aws_region,
|
|
40
|
+
aws_access_key_id=aws_access_key_id,
|
|
41
|
+
aws_secret_access_key=aws_secret_access_key,
|
|
42
|
+
aws_end_point_url=aws_end_point_url,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
self.__client: S3Client | None = None
|
|
46
|
+
self.__resource: S3ServiceResource | None = None
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def client(self) -> S3Client:
|
|
50
|
+
"""Client Connection"""
|
|
51
|
+
if self.__client is None:
|
|
52
|
+
self.__client = self.session.client
|
|
53
|
+
|
|
54
|
+
return self.__client
|
|
55
|
+
|
|
56
|
+
@client.setter
|
|
57
|
+
def client(self, value: S3Client):
|
|
58
|
+
logger.info("Setting Client")
|
|
59
|
+
self.__client = value
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def resource(self) -> S3ServiceResource:
|
|
63
|
+
"""Resource Connection"""
|
|
64
|
+
if self.__resource is None:
|
|
65
|
+
logger.info("Creating Resource")
|
|
66
|
+
self.__resource = self.session.resource
|
|
67
|
+
|
|
68
|
+
if self.raise_on_error and self.__resource is None:
|
|
69
|
+
raise RuntimeError("Resource is not available")
|
|
70
|
+
|
|
71
|
+
return self.__resource
|
|
72
|
+
|
|
73
|
+
@resource.setter
|
|
74
|
+
def resource(self, value: S3ServiceResource):
|
|
75
|
+
logger.info("Setting Resource")
|
|
76
|
+
self.__resource = value
|
|
@@ -0,0 +1,168 @@
|
|
|
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, List
|
|
8
|
+
from boto3_assist.utilities.numbers_utility import NumberUtility
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class EventData:
|
|
12
|
+
"""An Event Data Object"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, event: Dict[str, Any]):
|
|
15
|
+
self.__event = event
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def version(self) -> str | None:
|
|
19
|
+
"""Event Version"""
|
|
20
|
+
return self.__event.get("version")
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def id(self) -> str | None:
|
|
24
|
+
"""Event Id"""
|
|
25
|
+
return self.__event.get("id")
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def detail_type(self) -> str | None:
|
|
29
|
+
"""Event Detail Type"""
|
|
30
|
+
return self.__event.get("detail-type")
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def source(self) -> str | None:
|
|
34
|
+
"""Event Source"""
|
|
35
|
+
return self.__event.get("source")
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def account(self) -> str | None:
|
|
39
|
+
"""Event Account"""
|
|
40
|
+
return self.__event.get("account")
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def time(self) -> str | None:
|
|
44
|
+
"""Event Time"""
|
|
45
|
+
return self.__event.get("time")
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def region(self) -> str | None:
|
|
49
|
+
"""Event Region"""
|
|
50
|
+
return self.__event.get("region")
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def resources(self) -> List[str]:
|
|
54
|
+
"""Event Resources"""
|
|
55
|
+
return self.__event.get("resources", [])
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class S3BucketData:
|
|
59
|
+
"""S3 Bucket Data"""
|
|
60
|
+
|
|
61
|
+
def __init__(self, bucket_event_data: Dict[str, Any]):
|
|
62
|
+
self.__bucket = bucket_event_data
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def name(self) -> str | None:
|
|
66
|
+
"""Bucket Name Key"""
|
|
67
|
+
|
|
68
|
+
return self.__bucket.get("name")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class S3ObjectData:
|
|
72
|
+
"""S3 Object"""
|
|
73
|
+
|
|
74
|
+
def __init__(self, object_data: Dict[str, Any]):
|
|
75
|
+
self.__s3_object_data = object_data
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def key(self) -> str | None:
|
|
79
|
+
"""Object Key"""
|
|
80
|
+
return self.__s3_object_data.get("key")
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def size(self) -> int:
|
|
84
|
+
"""Object size in bytes"""
|
|
85
|
+
size = NumberUtility.to_number(self.__s3_object_data.get("size"))
|
|
86
|
+
return size
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def etag(self) -> str | None:
|
|
90
|
+
"""Object eTag"""
|
|
91
|
+
return self.__s3_object_data.get("etag")
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def version_id(self) -> str | None:
|
|
95
|
+
"""Object Version Id"""
|
|
96
|
+
return self.__s3_object_data.get("version-id")
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def sequencer(self) -> str | None:
|
|
100
|
+
"""Object eTag"""
|
|
101
|
+
return self.__s3_object_data.get("sequencer")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class S3EventDetail:
|
|
105
|
+
"""The Event Detail"""
|
|
106
|
+
|
|
107
|
+
def __init__(self, event: Dict[str, Any]):
|
|
108
|
+
self.__event = event
|
|
109
|
+
self.__s3_object_data: S3ObjectData | None = None
|
|
110
|
+
self.__s3_bucket_data: S3BucketData | None = None
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
def version(self) -> str | None:
|
|
114
|
+
"""Object Key"""
|
|
115
|
+
|
|
116
|
+
return self.__event.get("version")
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def bucket(self) -> S3BucketData:
|
|
120
|
+
"""S# Bucket Information"""
|
|
121
|
+
if not self.__s3_bucket_data:
|
|
122
|
+
self.__s3_bucket_data = S3BucketData(self.__event.get("bucket", {}))
|
|
123
|
+
return self.__s3_bucket_data
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def object(self) -> S3ObjectData:
|
|
127
|
+
"""S3 Object Information"""
|
|
128
|
+
if not self.__s3_object_data:
|
|
129
|
+
self.__s3_object_data = S3ObjectData(self.__event.get("object", {}))
|
|
130
|
+
|
|
131
|
+
return self.__s3_object_data
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def request_id(self) -> str | None:
|
|
135
|
+
"""Detail Request Id"""
|
|
136
|
+
|
|
137
|
+
return self.__event.get("request-id")
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def requester(self) -> str | None:
|
|
141
|
+
"""Detail Requestor"""
|
|
142
|
+
|
|
143
|
+
return self.__event.get("requester")
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def source_ip_address(self) -> str | None:
|
|
147
|
+
"""Source IP Address"""
|
|
148
|
+
|
|
149
|
+
return self.__event.get("source-ip-address")
|
|
150
|
+
|
|
151
|
+
@property
|
|
152
|
+
def reason(self) -> str | None:
|
|
153
|
+
"""Reason"""
|
|
154
|
+
|
|
155
|
+
return self.__event.get("reason")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class S3Event(EventData):
|
|
159
|
+
"""S3 Data Event"""
|
|
160
|
+
|
|
161
|
+
def __init__(self, event):
|
|
162
|
+
super().__init__(event)
|
|
163
|
+
self.__detail: S3EventDetail = S3EventDetail(event=event.get("detail", {}))
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def detail(self) -> S3EventDetail:
|
|
167
|
+
"""S3 Specific Detail"""
|
|
168
|
+
return self.__detail
|