boto3-assist 0.4.0__py3-none-any.whl → 0.5.1__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/boto3session.py +3 -0
- boto3_assist/cognito/cognito_connection.py +59 -0
- boto3_assist/cognito/cognito_utility.py +514 -0
- boto3_assist/cognito/user.py +27 -0
- boto3_assist/connection.py +14 -8
- boto3_assist/connection_tracker.py +75 -35
- boto3_assist/dynamodb/dynamodb_connection.py +11 -61
- boto3_assist/ec2/ec2_connection.py +12 -61
- boto3_assist/environment_services/environment_loader.py +1 -1
- boto3_assist/models/serializable_model.py +30 -0
- boto3_assist/s3/s3_connection.py +10 -51
- boto3_assist/utilities/datetime_utility.py +26 -0
- boto3_assist/utilities/dictionaroy_utility.py +26 -0
- boto3_assist/utilities/numbers_utility.py +286 -0
- boto3_assist/utilities/serialization_utility.py +68 -26
- boto3_assist/utilities/string_utility.py +59 -0
- boto3_assist/version.py +1 -1
- {boto3_assist-0.4.0.dist-info → boto3_assist-0.5.1.dist-info}/METADATA +1 -1
- {boto3_assist-0.4.0.dist-info → boto3_assist-0.5.1.dist-info}/RECORD +22 -17
- boto3_assist/dynamodb/dynamodb_connection_tracker.py +0 -17
- {boto3_assist-0.4.0.dist-info → boto3_assist-0.5.1.dist-info}/WHEEL +0 -0
- {boto3_assist-0.4.0.dist-info → boto3_assist-0.5.1.dist-info}/licenses/LICENSE-EXPLAINED.txt +0 -0
- {boto3_assist-0.4.0.dist-info → boto3_assist-0.5.1.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import math
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
from aws_lambda_powertools import Logger
|
|
4
|
+
|
|
5
|
+
logger = Logger()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class NumberUtility:
|
|
9
|
+
"""
|
|
10
|
+
Number Utility.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
def is_numeric(value: str | None | int | float) -> bool:
|
|
15
|
+
"""
|
|
16
|
+
Determines if a value is a number or not. This will remove any dashes, periods "-", "."
|
|
17
|
+
and then determine if the value is numeric
|
|
18
|
+
Args:
|
|
19
|
+
value (str): string value of a number
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
bool: _description_
|
|
23
|
+
"""
|
|
24
|
+
if value is None:
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
if value is None:
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
if str(value).isnumeric():
|
|
31
|
+
return True
|
|
32
|
+
try:
|
|
33
|
+
float(value)
|
|
34
|
+
return True
|
|
35
|
+
except: # noqa: E722, pylint: disable=w0702
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def are_numeric(values: List[int] | List[str] | List[float]) -> bool:
|
|
40
|
+
"""determines if a set of values are numeric or not"""
|
|
41
|
+
for value in values:
|
|
42
|
+
if not NumberUtility.is_numeric(value):
|
|
43
|
+
return False
|
|
44
|
+
|
|
45
|
+
return True
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def to_number_or_none(value: str) -> float | int | None:
|
|
49
|
+
"""Converts a string to a number."""
|
|
50
|
+
if value is not None and NumberUtility.is_numeric(value):
|
|
51
|
+
if "." in str(value):
|
|
52
|
+
return float(value)
|
|
53
|
+
else:
|
|
54
|
+
return int(value)
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def to_float(
|
|
59
|
+
value: str | float | int, raise_errors: Optional[bool] = False
|
|
60
|
+
) -> float:
|
|
61
|
+
"""_summary_
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
value (str | float | int): _description_
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
float: returns a float of zero.
|
|
70
|
+
"""
|
|
71
|
+
try:
|
|
72
|
+
return float(value)
|
|
73
|
+
except: # noqa: E722, pylint: disable=w0702
|
|
74
|
+
logger.error(f"Unable to convert {value} to float")
|
|
75
|
+
if raise_errors:
|
|
76
|
+
raise
|
|
77
|
+
return 0.0
|
|
78
|
+
|
|
79
|
+
@staticmethod
|
|
80
|
+
def get_max_length(items: List[str] | List[int] | List[float]) -> int:
|
|
81
|
+
"""Returns the max length of an item in a list."""
|
|
82
|
+
length = 0
|
|
83
|
+
for item in items:
|
|
84
|
+
if len(str(item)) > length:
|
|
85
|
+
length = len(str(item))
|
|
86
|
+
|
|
87
|
+
return length
|
|
88
|
+
|
|
89
|
+
@staticmethod
|
|
90
|
+
def to_significant_digits_rounded(value, significant_digits=10):
|
|
91
|
+
"""
|
|
92
|
+
converts to significant digits
|
|
93
|
+
"""
|
|
94
|
+
result = math.floor(value * 10**significant_digits) / 10**significant_digits
|
|
95
|
+
to_the_right = len(f"{int(value)}")
|
|
96
|
+
f_string_number = (
|
|
97
|
+
f"{value:.{significant_digits + to_the_right}g}" # Using f-string
|
|
98
|
+
)
|
|
99
|
+
result = float(f_string_number)
|
|
100
|
+
|
|
101
|
+
return result
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
def get_number_of_decimal_places(number: float) -> int:
|
|
105
|
+
"""
|
|
106
|
+
Gets the number decimal places
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
number (float): the number to inspect
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
int: number of decimal places
|
|
113
|
+
"""
|
|
114
|
+
number_str = f"{number}"
|
|
115
|
+
if "." in number_str:
|
|
116
|
+
to_the_right = number_str.split(".")[1]
|
|
117
|
+
return len(to_the_right)
|
|
118
|
+
|
|
119
|
+
return 0
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def to_significant_digits(number: float, significant_digits: int = 10):
|
|
123
|
+
"""To Significat Digits"""
|
|
124
|
+
# make sure we're dealing with a number
|
|
125
|
+
number = float(number)
|
|
126
|
+
if significant_digits < 0:
|
|
127
|
+
raise ValueError("Decimal places must be non-negative")
|
|
128
|
+
else:
|
|
129
|
+
number_str = f"{number}"
|
|
130
|
+
if "." in number_str:
|
|
131
|
+
decimal_point_index = number_str.index(".")
|
|
132
|
+
number_of_decimal_places = NumberUtility.get_number_of_decimal_places(
|
|
133
|
+
number
|
|
134
|
+
)
|
|
135
|
+
if number_of_decimal_places > significant_digits:
|
|
136
|
+
return NumberUtility.to_significant_digits_rounded(
|
|
137
|
+
number, significant_digits
|
|
138
|
+
)
|
|
139
|
+
else:
|
|
140
|
+
cutoff_index = decimal_point_index + significant_digits + 1
|
|
141
|
+
truncated_str = number_str[:cutoff_index]
|
|
142
|
+
return float(truncated_str)
|
|
143
|
+
else:
|
|
144
|
+
return number
|
|
145
|
+
|
|
146
|
+
@staticmethod
|
|
147
|
+
def is_decimal(value):
|
|
148
|
+
is_numeric = NumberUtility.is_numeric(value)
|
|
149
|
+
contains_decimal = "." in str(value)
|
|
150
|
+
|
|
151
|
+
return is_numeric and contains_decimal
|
|
152
|
+
|
|
153
|
+
@staticmethod
|
|
154
|
+
def percent_difference(number1, number2):
|
|
155
|
+
"""
|
|
156
|
+
Calculate the percent difference between two numbers.
|
|
157
|
+
|
|
158
|
+
Parameters:
|
|
159
|
+
- number1: The first number.
|
|
160
|
+
- number2: The second number.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
- The percent difference between the two numbers.
|
|
164
|
+
"""
|
|
165
|
+
number1 = float(number1)
|
|
166
|
+
number2 = float(number2)
|
|
167
|
+
# Calculate the absolute difference between the two numbers
|
|
168
|
+
difference = abs(number1 - number2)
|
|
169
|
+
|
|
170
|
+
# Calculate the average of the two numbers
|
|
171
|
+
average = (number1 + number2) / 2
|
|
172
|
+
|
|
173
|
+
if difference > 0:
|
|
174
|
+
# Calculate the percent difference
|
|
175
|
+
percent_diff = (difference / average) * 100
|
|
176
|
+
|
|
177
|
+
return percent_diff
|
|
178
|
+
|
|
179
|
+
return 0.0
|
|
180
|
+
|
|
181
|
+
@staticmethod
|
|
182
|
+
def to_significant_figure(
|
|
183
|
+
number: int | float | str, sig_figs: int
|
|
184
|
+
) -> int | float | str:
|
|
185
|
+
"""
|
|
186
|
+
Formats a number to it's significant figures.
|
|
187
|
+
Examples
|
|
188
|
+
12345.6789, 4 = 12350
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
number (int | float | str): a valid number
|
|
192
|
+
sig_figs (int): the number of signigicant figures
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
int | float: the value after applying a significant figure
|
|
196
|
+
"""
|
|
197
|
+
# just used for tracking
|
|
198
|
+
original_value = number
|
|
199
|
+
value: int | float | str = 0
|
|
200
|
+
if str(number).lower() == "nan":
|
|
201
|
+
return number
|
|
202
|
+
|
|
203
|
+
if NumberUtility.is_numeric(number) and isinstance(number, str):
|
|
204
|
+
if "." in str(number):
|
|
205
|
+
number = float(number)
|
|
206
|
+
else:
|
|
207
|
+
number = int(number)
|
|
208
|
+
|
|
209
|
+
if number == 0:
|
|
210
|
+
if sig_figs > 1:
|
|
211
|
+
value = "0." + "0" * (sig_figs - 1)
|
|
212
|
+
else:
|
|
213
|
+
value = 0
|
|
214
|
+
|
|
215
|
+
else:
|
|
216
|
+
scale = int(math.floor(math.log10(abs(float(number)))))
|
|
217
|
+
pre_power = int(scale - sig_figs + 1)
|
|
218
|
+
|
|
219
|
+
factor = 10 ** (pre_power)
|
|
220
|
+
rounded = round(number / factor) * factor
|
|
221
|
+
|
|
222
|
+
if not isinstance(rounded, int):
|
|
223
|
+
value = f"{rounded:.{sig_figs}g}"
|
|
224
|
+
else:
|
|
225
|
+
value = f"{rounded}"
|
|
226
|
+
|
|
227
|
+
if "." in f"{value}" and len(f"{value}") >= (sig_figs):
|
|
228
|
+
value = float(value)
|
|
229
|
+
elif "." in f"{value}" and len(f"{value}") <= (sig_figs + 1):
|
|
230
|
+
# there are more sig figures in the length of the figures
|
|
231
|
+
# adding 1 to account for the decimal place
|
|
232
|
+
value = float(value)
|
|
233
|
+
else:
|
|
234
|
+
# due to the scientific express we need to float it first
|
|
235
|
+
value = float(value)
|
|
236
|
+
value = int(value)
|
|
237
|
+
|
|
238
|
+
logger.debug(
|
|
239
|
+
{
|
|
240
|
+
"source": "",
|
|
241
|
+
"sig": sig_figs,
|
|
242
|
+
"value": {"original": original_value, "converted": value},
|
|
243
|
+
}
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
return value
|
|
247
|
+
|
|
248
|
+
@staticmethod
|
|
249
|
+
def get_significant_figure(value) -> int:
|
|
250
|
+
"""
|
|
251
|
+
Calculate the number of significant figures in a number.
|
|
252
|
+
Removes leading and trailing zeros for float numbers.
|
|
253
|
+
"""
|
|
254
|
+
if not value:
|
|
255
|
+
return 0
|
|
256
|
+
if isinstance(value, int) or isinstance(value, int):
|
|
257
|
+
return len(str(value).strip("0"))
|
|
258
|
+
elif isinstance(value, float):
|
|
259
|
+
if value == 0:
|
|
260
|
+
return 0
|
|
261
|
+
else:
|
|
262
|
+
length: int = 0
|
|
263
|
+
if value > 1:
|
|
264
|
+
value_str = f"{value}"
|
|
265
|
+
digits = value_str
|
|
266
|
+
number = digits.split(".")
|
|
267
|
+
left = number[0].lstrip("0")
|
|
268
|
+
right = ""
|
|
269
|
+
if len(number) > 1:
|
|
270
|
+
right = f"{number[1].rstrip('0')}"
|
|
271
|
+
|
|
272
|
+
digits_stripped = f"{left}{right}"
|
|
273
|
+
# Remove decimal point and trailing zeros
|
|
274
|
+
length = len(digits_stripped)
|
|
275
|
+
|
|
276
|
+
else:
|
|
277
|
+
value_str = f"{value}"
|
|
278
|
+
# remove the "." remove all left and right decimals
|
|
279
|
+
# example: 0.0012 becomes 12 with sig digit of 2
|
|
280
|
+
digits_stripped = value_str.replace(".", "").rstrip("0").lstrip("0")
|
|
281
|
+
length = len(digits_stripped)
|
|
282
|
+
|
|
283
|
+
return length
|
|
284
|
+
|
|
285
|
+
else:
|
|
286
|
+
return 0
|
|
@@ -5,11 +5,11 @@ from decimal import Decimal
|
|
|
5
5
|
from typing import Dict, List, TypeVar
|
|
6
6
|
import json
|
|
7
7
|
import jsons
|
|
8
|
-
from aws_lambda_powertools import Logger
|
|
8
|
+
from aws_lambda_powertools import Logger
|
|
9
9
|
|
|
10
10
|
T = TypeVar("T")
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
logger = Logger()
|
|
14
14
|
|
|
15
15
|
|
|
@@ -67,7 +67,7 @@ class Serialization:
|
|
|
67
67
|
raise ValueError("Unable to convert object to dictionary")
|
|
68
68
|
|
|
69
69
|
@staticmethod
|
|
70
|
-
def map(source: object, target: T) -> T | None:
|
|
70
|
+
def map(source: object, target: T, coerce: bool = True) -> T | None:
|
|
71
71
|
"""Map an object from one object to another"""
|
|
72
72
|
source_dict: dict | object
|
|
73
73
|
if isinstance(source, dict):
|
|
@@ -76,12 +76,26 @@ class Serialization:
|
|
|
76
76
|
source_dict = Serialization.convert_object_to_dict(source)
|
|
77
77
|
if not isinstance(source_dict, dict):
|
|
78
78
|
return None
|
|
79
|
-
return Serialization.load_properties(
|
|
79
|
+
return Serialization.load_properties(
|
|
80
|
+
source=source_dict, target=target, coerce=coerce
|
|
81
|
+
)
|
|
80
82
|
|
|
81
83
|
@staticmethod
|
|
82
|
-
def load_properties(
|
|
84
|
+
def load_properties(
|
|
85
|
+
source: dict,
|
|
86
|
+
target: T,
|
|
87
|
+
coerce: bool = True,
|
|
88
|
+
) -> T | None:
|
|
83
89
|
"""
|
|
84
|
-
Converts a source to
|
|
90
|
+
Converts a source dictionary to a target object.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
source (dict): The source dictionary containing properties.
|
|
94
|
+
target (T): The target object to populate.
|
|
95
|
+
coerce (bool): If True, attempts to convert values to the target attribute types. If False, raises an error for type mismatches.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
T | None: The populated target object, or None if an error occurred.
|
|
85
99
|
"""
|
|
86
100
|
# Ensure target is an instance of the class
|
|
87
101
|
if isinstance(target, type):
|
|
@@ -95,28 +109,56 @@ class Serialization:
|
|
|
95
109
|
setattr(target, "__actively_serializing_data__", True)
|
|
96
110
|
|
|
97
111
|
for key, value in source.items():
|
|
98
|
-
if Serialization.has_attribute(target, key):
|
|
112
|
+
if Serialization.has_attribute(target, key):
|
|
99
113
|
attr = getattr(target, key)
|
|
100
|
-
|
|
101
|
-
|
|
114
|
+
expected_type = type(attr)
|
|
115
|
+
|
|
116
|
+
try:
|
|
117
|
+
if isinstance(attr, (int, float, str, bool)):
|
|
118
|
+
if not isinstance(value, expected_type):
|
|
119
|
+
if coerce:
|
|
120
|
+
# Attempt to coerce the value to the expected type
|
|
121
|
+
try:
|
|
122
|
+
value = expected_type(value)
|
|
123
|
+
except ValueError as e:
|
|
124
|
+
logger.warning(
|
|
125
|
+
f"Warning coercing attribute {key} with value {value}: {e}"
|
|
126
|
+
)
|
|
127
|
+
# TODO: should we set numbers to 0 or a NaN or raise an error
|
|
128
|
+
|
|
129
|
+
setattr(target, key, value)
|
|
130
|
+
# raise ValueError( # pylint: disable=w0707
|
|
131
|
+
# f"Type mismatch for attribute {key}. Expected {expected_type}, got {type(value)}."
|
|
132
|
+
# )
|
|
133
|
+
else:
|
|
134
|
+
raise ValueError(
|
|
135
|
+
f"Type mismatch for attribute {key}. Expected {expected_type}, got {type(value)}."
|
|
136
|
+
)
|
|
137
|
+
setattr(target, key, value)
|
|
138
|
+
elif isinstance(attr, type(None)):
|
|
139
|
+
setattr(target, key, value)
|
|
140
|
+
elif isinstance(attr, list) and isinstance(value, list):
|
|
141
|
+
attr.clear()
|
|
142
|
+
attr.extend(value)
|
|
143
|
+
elif isinstance(attr, dict) and isinstance(value, dict):
|
|
144
|
+
Serialization.load_properties(value, attr, coerce=coerce)
|
|
145
|
+
elif hasattr(attr, "__dict__") and isinstance(value, dict):
|
|
146
|
+
Serialization.load_properties(value, attr, coerce=coerce)
|
|
147
|
+
else:
|
|
102
148
|
setattr(target, key, value)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
elif hasattr(attr, "__dict__") and isinstance(value, dict):
|
|
117
|
-
Serialization.load_properties(value, attr)
|
|
118
|
-
else:
|
|
119
|
-
setattr(target, key, value)
|
|
149
|
+
except ValueError as e:
|
|
150
|
+
logger.error(
|
|
151
|
+
f"Error setting attribute {key} with value {value}: {e}"
|
|
152
|
+
)
|
|
153
|
+
raise
|
|
154
|
+
except Exception as e: # pylint: disable=w0718
|
|
155
|
+
logger.error(
|
|
156
|
+
f"Error setting attribute {key} with value {value}: {e}. "
|
|
157
|
+
"This usually occurs on properties that don't have setters. "
|
|
158
|
+
"You can add a setter (even with a pass action) for this property, "
|
|
159
|
+
"decorate it with the @exclude_from_serialization "
|
|
160
|
+
"or ignore this error. "
|
|
161
|
+
)
|
|
120
162
|
|
|
121
163
|
if hasattr(target, "__actively_serializing_data__"):
|
|
122
164
|
setattr(target, "__actively_serializing_data__", False)
|
|
@@ -7,11 +7,13 @@ MIT License. See Project Root for the license information.
|
|
|
7
7
|
import hashlib
|
|
8
8
|
import secrets
|
|
9
9
|
import string
|
|
10
|
+
import time
|
|
10
11
|
from datetime import datetime
|
|
11
12
|
from decimal import Decimal
|
|
12
13
|
import uuid
|
|
13
14
|
import json
|
|
14
15
|
from aws_lambda_powertools import Logger
|
|
16
|
+
from boto3_assist.utilities.datetime_utility import DatetimeUtility
|
|
15
17
|
|
|
16
18
|
logger = Logger()
|
|
17
19
|
|
|
@@ -230,3 +232,60 @@ class StringUtility:
|
|
|
230
232
|
size = int(len(_bytes))
|
|
231
233
|
|
|
232
234
|
return size
|
|
235
|
+
|
|
236
|
+
@staticmethod
|
|
237
|
+
def generate_sortable_uuid():
|
|
238
|
+
"""
|
|
239
|
+
Generates a unique id for the execution event
|
|
240
|
+
"""
|
|
241
|
+
epoch_time = time.time()
|
|
242
|
+
sortable_uuid: uuid.UUID = DatetimeUtility.uuid1_utc(timestamp=epoch_time)
|
|
243
|
+
|
|
244
|
+
time_stamp = str(epoch_time).replace(".", "-")
|
|
245
|
+
sortable_id = f"{time_stamp}:{str(sortable_uuid)}"
|
|
246
|
+
return sortable_id
|
|
247
|
+
|
|
248
|
+
@staticmethod
|
|
249
|
+
def to_bool(value: str | bool | int | None) -> bool:
|
|
250
|
+
"""
|
|
251
|
+
Converts a string or boolean value to a boolean.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
value (str | bool | int | None): The value to convert.
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
bool: The converted boolean value.
|
|
258
|
+
|
|
259
|
+
Raises:
|
|
260
|
+
ValueError: If the input value is not a valid boolean or string representation.
|
|
261
|
+
"""
|
|
262
|
+
return StringUtility.to_boolean(value)
|
|
263
|
+
|
|
264
|
+
@staticmethod
|
|
265
|
+
def to_boolean(value: str | bool | int | None) -> bool:
|
|
266
|
+
"""
|
|
267
|
+
Converts a string or boolean value to a boolean.
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
value (str | bool | int | None): The value to convert.
|
|
271
|
+
|
|
272
|
+
Returns:
|
|
273
|
+
bool: The converted boolean value.
|
|
274
|
+
|
|
275
|
+
Raises:
|
|
276
|
+
ValueError: If the input value is not a valid boolean or string representation.
|
|
277
|
+
"""
|
|
278
|
+
if isinstance(value, bool):
|
|
279
|
+
return value
|
|
280
|
+
if isinstance(value, str):
|
|
281
|
+
value = str(value).lower().strip()
|
|
282
|
+
if value in ("true", "1", "t", "y", "yes"):
|
|
283
|
+
return True
|
|
284
|
+
if value in ("false", "0", "f", "n", "no"):
|
|
285
|
+
return False
|
|
286
|
+
elif isinstance(value, int):
|
|
287
|
+
return bool(value)
|
|
288
|
+
elif value is None:
|
|
289
|
+
return False
|
|
290
|
+
else:
|
|
291
|
+
raise ValueError(f"Invalid boolean value: {value}")
|
boto3_assist/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '0.
|
|
1
|
+
__version__ = '0.5.1'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
boto3_assist/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
boto3_assist/boto3session.py,sha256=
|
|
3
|
-
boto3_assist/connection.py,sha256=
|
|
4
|
-
boto3_assist/connection_tracker.py,sha256=
|
|
2
|
+
boto3_assist/boto3session.py,sha256=Q9sByNC0r_aMQfHnIEnxtTaiCMUqikm8UeSTxV7-Np0,6632
|
|
3
|
+
boto3_assist/connection.py,sha256=CNGkAIRyfrELoWrV0ziQBA3oHacNFuLL3i8faUPRiO0,3486
|
|
4
|
+
boto3_assist/connection_tracker.py,sha256=bfImvNVX-0Lhb-ombOurWUpNLdI0qVDil-kokBdIFkY,4345
|
|
5
5
|
boto3_assist/http_status_codes.py,sha256=G0zRSWenwavYKETvDF9tNVUXQz3Ae2gXdBETYbjvJe8,3284
|
|
6
|
-
boto3_assist/version.py,sha256=
|
|
6
|
+
boto3_assist/version.py,sha256=s8Yq9Om1yBxrMA7xYQ5Y13Paeuxnq99NxhyjuPlnH6A,22
|
|
7
7
|
boto3_assist/aws_lambda/event_info.py,sha256=OkZ4WzuGaHEu_T8sB188KBgShAJhZpWASALKRGBOhMg,14648
|
|
8
8
|
boto3_assist/cloudwatch/cloudwatch_connection.py,sha256=mnGWaLSQpHh5EeY7Ek_2o9JKHJxOELIYtQVMX1IaHn4,2480
|
|
9
9
|
boto3_assist/cloudwatch/cloudwatch_connection_tracker.py,sha256=mzRtO1uHrcfJNh1XrGEiXdTqxwEP8d1RqJkraMNkgK0,410
|
|
@@ -11,10 +11,12 @@ boto3_assist/cloudwatch/cloudwatch_log_connection.py,sha256=qQMZHjUJ6gA8wU9utjQh
|
|
|
11
11
|
boto3_assist/cloudwatch/cloudwatch_logs.py,sha256=VtI0OnFjX1l4RYVvA8tvveGkPwAogtrplnflZ4dQSNM,1204
|
|
12
12
|
boto3_assist/cloudwatch/cloudwatch_query.py,sha256=uNhSb1Gfp99v8BaHmCnCKs63j4MMU4WveqBavCJyhGY,6409
|
|
13
13
|
boto3_assist/cognito/cognito_authorizer.py,sha256=ONcxzjTACgVYl6qI9kJAQ5SoRMtVHYGDeuKi5QqJvOY,5837
|
|
14
|
+
boto3_assist/cognito/cognito_connection.py,sha256=deuXR3cNHz0mCYff2k0LfAvK--9OkqehWp0Bl--lDuw,1607
|
|
15
|
+
boto3_assist/cognito/cognito_utility.py,sha256=kjzd2PcCCP9GbxlMlgYEIQE1FSyPPjsRPjr6-kN08Jc,18238
|
|
14
16
|
boto3_assist/cognito/jwks_cache.py,sha256=1Y9r-YfQ8qrgZN5xYPvjUEEV0vthbdcPdAIaPbZP7kU,373
|
|
17
|
+
boto3_assist/cognito/user.py,sha256=qc44qLx3gwq6q2zMxcPQze1EjeZwy5Kuav93vbe-4WU,820
|
|
15
18
|
boto3_assist/dynamodb/dynamodb.py,sha256=q3U4uYqnKX1_u5TXv8Iq94JrBad16q0rL_vKxQyR_3k,15772
|
|
16
|
-
boto3_assist/dynamodb/dynamodb_connection.py,sha256=
|
|
17
|
-
boto3_assist/dynamodb/dynamodb_connection_tracker.py,sha256=0BWHRfi5_vjkJLuCSX6sYwvA6wc7BSYCQnGrzbhfyKA,404
|
|
19
|
+
boto3_assist/dynamodb/dynamodb_connection.py,sha256=x6Ylb_uVAY5TS0AIBUNOSyywKIqros3xX8diLTjZUsc,3275
|
|
18
20
|
boto3_assist/dynamodb/dynamodb_helpers.py,sha256=ajpTJ5bJOm9PDgE2Zx9p2zkTRFV4xswqJRS81SOTn1s,12198
|
|
19
21
|
boto3_assist/dynamodb/dynamodb_importer.py,sha256=nCKsyRQeMqDSf0Q5mQ_X_oVIg4PRnu0hcUzZnBli610,3471
|
|
20
22
|
boto3_assist/dynamodb/dynamodb_index.py,sha256=D0Lq121qk1cXeMetPeqnzvv6CXd0XfEygfdUXaljLG8,8551
|
|
@@ -27,21 +29,24 @@ boto3_assist/dynamodb/dynamodb_reserved_words.py,sha256=p0irNBSqGe4rd2FwWQqbRJWr
|
|
|
27
29
|
boto3_assist/dynamodb/dynamodb_reserved_words.txt,sha256=rvctS63Cv3i9SHmPq2Unmj6RZyQ-OMqxUXsNhtbg1is,4136
|
|
28
30
|
boto3_assist/dynamodb/readme.md,sha256=wNMzdRwk0qRV0kE88UUYnJos3pEK0HNjEIVkq2PATf8,1490
|
|
29
31
|
boto3_assist/dynamodb/troubleshooting.md,sha256=uGpBaBUt_MyzjzwFOLOe0udTgcvaOpiTFxfj7ilLNkM,136
|
|
30
|
-
boto3_assist/ec2/ec2_connection.py,sha256=
|
|
32
|
+
boto3_assist/ec2/ec2_connection.py,sha256=IrtaidH6_SF5l3OeNehRsTlC-sX7EURVqcO-U6P6ff8,1318
|
|
31
33
|
boto3_assist/environment_services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
-
boto3_assist/environment_services/environment_loader.py,sha256=
|
|
34
|
+
boto3_assist/environment_services/environment_loader.py,sha256=zCA4mRdVWMLKzjDRvrJbhQfRVP4HAMGpuQFi07zzULk,3396
|
|
33
35
|
boto3_assist/environment_services/environment_variables.py,sha256=4ccBKdPt6O7hcRT3zBHd8vqu8yQU8udmoD5RLAT3iMs,6801
|
|
34
36
|
boto3_assist/errors/custom_exceptions.py,sha256=zC2V2Y4PUtKj3uLPn8mB-JessksKWJWvKM9kp1dmvt8,760
|
|
37
|
+
boto3_assist/models/serializable_model.py,sha256=8CunaU2YDWs9vK2BShShnyAdktmeZ3R_o7p8Yt70nYQ,829
|
|
35
38
|
boto3_assist/s3/s3.py,sha256=DFCJs5z1mMIT8nZfnqPyr_cvhi9-FePuYH--tzD7b5E,17104
|
|
36
|
-
boto3_assist/s3/s3_connection.py,sha256=
|
|
37
|
-
boto3_assist/utilities/datetime_utility.py,sha256=
|
|
39
|
+
boto3_assist/s3/s3_connection.py,sha256=FI1AhZV4UbTXQRTb4TqL9mv88Gt018rPZVFBvLetVAw,2163
|
|
40
|
+
boto3_assist/utilities/datetime_utility.py,sha256=dgAMB9VqakrYIPXlSoVQiLSsc_yhrJK4gMfJO9mX90w,11112
|
|
41
|
+
boto3_assist/utilities/dictionaroy_utility.py,sha256=PjUrerEd6uhmw37A-k7xe_DWHvXZGGoMqT6xjUqmWBI,893
|
|
38
42
|
boto3_assist/utilities/file_operations.py,sha256=Zy8fu8fpuVNf7U9NimrLdy5FRF71XSI159cnRdzmzGY,3411
|
|
39
43
|
boto3_assist/utilities/http_utility.py,sha256=koFv7Va-8ng-47Nt1K2Sh7Ti95e62IYs9VMLlGh9Kt4,1173
|
|
40
44
|
boto3_assist/utilities/logging_utility.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
41
|
-
boto3_assist/utilities/
|
|
42
|
-
boto3_assist/utilities/
|
|
43
|
-
boto3_assist
|
|
44
|
-
boto3_assist-0.
|
|
45
|
-
boto3_assist-0.
|
|
46
|
-
boto3_assist-0.
|
|
47
|
-
boto3_assist-0.
|
|
45
|
+
boto3_assist/utilities/numbers_utility.py,sha256=KIiNkBSRbfNWvtXG5SdHp625LTiW12VtADUa4ZlWMFo,8709
|
|
46
|
+
boto3_assist/utilities/serialization_utility.py,sha256=p9QQfc6EDOtD-mB6Ujhv-BRpDn3DCCG2z5VmXG1kmb0,7768
|
|
47
|
+
boto3_assist/utilities/string_utility.py,sha256=sBY80aQO-fTRanlHryZFMQBxdo6OvLRvnZjZrQepHlI,9283
|
|
48
|
+
boto3_assist-0.5.1.dist-info/METADATA,sha256=r5iNwKDiUS06CIskAGuHnpvW3wXfD97QznVQhe07jWQ,1728
|
|
49
|
+
boto3_assist-0.5.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
50
|
+
boto3_assist-0.5.1.dist-info/licenses/LICENSE-EXPLAINED.txt,sha256=WFREvTpfTjPjDHpOLADxJpCKpIla3Ht87RUUGii4ODU,606
|
|
51
|
+
boto3_assist-0.5.1.dist-info/licenses/LICENSE.txt,sha256=PXDhFWS5L5aOTkVhNvoitHKbAkgxqMI2uUPQyrnXGiI,1105
|
|
52
|
+
boto3_assist-0.5.1.dist-info/RECORD,,
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Geek Cafe, LLC
|
|
3
|
-
Maintainers: Eric Wilson
|
|
4
|
-
MIT License. See Project Root for the license information.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from boto3_assist.connection_tracker import ConnectionTracker
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class DynamoDBConnectionTracker(ConnectionTracker):
|
|
11
|
-
"""
|
|
12
|
-
Tracks DynamoDB Connection Requests.
|
|
13
|
-
Useful in for performance tuning and debugging.
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
def __init__(self) -> None:
|
|
17
|
-
super().__init__("DynamoDB")
|
|
File without changes
|
{boto3_assist-0.4.0.dist-info → boto3_assist-0.5.1.dist-info}/licenses/LICENSE-EXPLAINED.txt
RENAMED
|
File without changes
|
|
File without changes
|