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.
@@ -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, Tracer
8
+ from aws_lambda_powertools import Logger
9
9
 
10
10
  T = TypeVar("T")
11
11
 
12
- tracer = Tracer()
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(source_dict, target=target)
79
+ return Serialization.load_properties(
80
+ source=source_dict, target=target, coerce=coerce
81
+ )
80
82
 
81
83
  @staticmethod
82
- def load_properties(source: dict, target: T) -> T | None:
84
+ def load_properties(
85
+ source: dict,
86
+ target: T,
87
+ coerce: bool = True,
88
+ ) -> T | None:
83
89
  """
84
- Converts a source to an object
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): # hasattr(target, key):
112
+ if Serialization.has_attribute(target, key):
99
113
  attr = getattr(target, key)
100
- if isinstance(attr, (int, float, str, bool, type(None))):
101
- try:
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
- except Exception as e: # pylint: disable=w0718
104
- logger.error(
105
- f"Error setting attribute {key} with value {value}: {e}. "
106
- "This usually occurs on properties that don't have setters. "
107
- "You can add a setter (even with a pass action) for this property, "
108
- "decorate it with the @exclude_from_serialization "
109
- "or ignore this error. "
110
- )
111
- elif isinstance(attr, list) and isinstance(value, list):
112
- attr.clear()
113
- attr.extend(value)
114
- elif isinstance(attr, dict) and isinstance(value, dict):
115
- Serialization.load_properties(value, attr)
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.4.0'
1
+ __version__ = '0.5.1'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boto3_assist
3
- Version: 0.4.0
3
+ Version: 0.5.1
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
@@ -1,9 +1,9 @@
1
1
  boto3_assist/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- boto3_assist/boto3session.py,sha256=NWhWtYR3143thEbTpoklkwdz77-fTMs-QsoQdqfRm6E,6430
3
- boto3_assist/connection.py,sha256=EJlGueLIYqMSKs7aQlThK1S0Zkb8dOYBWch1iRZdgUI,3233
4
- boto3_assist/connection_tracker.py,sha256=_s1t7h2DOi3CCIHIr_HIKyGjku65WR-HJ_v8vJHDvO0,2977
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=2eiWQI55fd-roDdkt4Hvl9WzrTJ4xQo33VzFud6D03U,22
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=hr4IGbbEE73fh375tj3_XtYAwwDV0s7z1-6JK_1Tc30,5263
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=VT_hnu_behs9mf1Prggo5U9c9KAwbnLBTSZkmu4gp30,3277
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=jvG1xwMtgkZqu70NbjG1b1IefKiWgaidjZZoqsSfULk,3370
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=fMD1FxQazJ9gSFDrRmrv7YJE5QnCesGoWC1b5Dba_Jo,3774
37
- boto3_assist/utilities/datetime_utility.py,sha256=TbqGQkJDTahqvaZAIV550nhYnW1Bsq0Hdu3Go6P4RRs,10282
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/serialization_utility.py,sha256=vsipCQZu91hApkJ8tKRTxBa8kNRvn06ED-isquqAVQQ,5744
42
- boto3_assist/utilities/string_utility.py,sha256=fzsZkldRYtdkIqR0kD-TlHH4fh4iMtYvo_U3UNZhN7U,7427
43
- boto3_assist-0.4.0.dist-info/METADATA,sha256=6PglW0CMu-LSfBs74ViaxrykaJG96KtCspwIIPcP0PU,1728
44
- boto3_assist-0.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
45
- boto3_assist-0.4.0.dist-info/licenses/LICENSE-EXPLAINED.txt,sha256=WFREvTpfTjPjDHpOLADxJpCKpIla3Ht87RUUGii4ODU,606
46
- boto3_assist-0.4.0.dist-info/licenses/LICENSE.txt,sha256=PXDhFWS5L5aOTkVhNvoitHKbAkgxqMI2uUPQyrnXGiI,1105
47
- boto3_assist-0.4.0.dist-info/RECORD,,
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")