boto3-assist 0.2.9__py3-none-any.whl → 0.2.11__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.
@@ -94,7 +94,7 @@ class DynamoDB(DynamoDBConnection):
94
94
  except Exception as e: # pylint: disable=w0718
95
95
  logger.exception(e)
96
96
  raise RuntimeError(
97
- "An error occured during model converation. The entry was not saved."
97
+ "An error occured during model converation. The entry was not saved. "
98
98
  ) from e
99
99
 
100
100
  if isinstance(item, dict):
@@ -28,6 +28,14 @@ class DynamoDBIndexes:
28
28
  def add_primary(self, index: DynamoDBIndex):
29
29
  """Add an index"""
30
30
  index.name = DynamoDBIndexes.PRIMARY_INDEX
31
+
32
+ if index.name in self.__indexes:
33
+ raise ValueError(
34
+ f"The index {index.name} is already defined in your model somewhere. "
35
+ "This error is generated to protect you from unforseen issues. "
36
+ "If you models are inheriting from other models, you may have the primary defined twice."
37
+ )
38
+
31
39
  self.__indexes[DynamoDBIndexes.PRIMARY_INDEX] = index
32
40
 
33
41
  def add_secondary(self, index: DynamoDBIndex):
@@ -37,7 +45,11 @@ class DynamoDBIndexes:
37
45
 
38
46
  # if the index already exists, raise an exception
39
47
  if index.name in self.__indexes:
40
- raise ValueError(f"Index {index.name} already exists")
48
+ raise ValueError(
49
+ f"The index {index.name} is already defined in your model somewhere. "
50
+ "This error is generated to protect you from unforseen issues. "
51
+ "If you models are inheriting from other models, you may have the primary defined twice."
52
+ )
41
53
  if index.name == DynamoDBIndexes.PRIMARY_INDEX:
42
54
  raise ValueError(f"Index {index.name} is reserved for the primary index")
43
55
  if index.partition_key is None:
@@ -49,6 +49,7 @@ class DynamoDBModelBase:
49
49
  self.__indexes: DynamoDBIndexes | None = None
50
50
  self.__reserved_words: DynamoDBReservedWords = DynamoDBReservedWords()
51
51
  self.__auto_generate_projections: bool = auto_generate_projections
52
+ self.__actively_serializing_data__: bool = False
52
53
 
53
54
  @property
54
55
  @exclude_from_serialization
@@ -67,7 +67,6 @@ class Serialization:
67
67
  raise ValueError("Unable to convert object to dictionary")
68
68
 
69
69
  @staticmethod
70
- @tracer.capture_method
71
70
  def map(source: object, target: T) -> T | None:
72
71
  """Map an object from one object to another"""
73
72
  source_dict: dict | object
@@ -80,7 +79,6 @@ class Serialization:
80
79
  return Serialization.load_properties(source_dict, target=target)
81
80
 
82
81
  @staticmethod
83
- @tracer.capture_method
84
82
  def load_properties(source: dict, target: T) -> T | None:
85
83
  """
86
84
  Converts a source to an object
@@ -93,8 +91,11 @@ class Serialization:
93
91
  if hasattr(source, "__dict__"):
94
92
  source = source.__dict__
95
93
 
94
+ if hasattr(target, "__actively_serializing_data__"):
95
+ setattr(target, "__actively_serializing_data__", True)
96
+
96
97
  for key, value in source.items():
97
- if hasattr(target, key):
98
+ if Serialization.has_attribute(target, key): # hasattr(target, key):
98
99
  attr = getattr(target, key)
99
100
  if isinstance(attr, (int, float, str, bool, type(None))):
100
101
  try:
@@ -116,4 +117,29 @@ class Serialization:
116
117
  Serialization.load_properties(value, attr)
117
118
  else:
118
119
  setattr(target, key, value)
120
+
121
+ if hasattr(target, "__actively_serializing_data__"):
122
+ setattr(target, "__actively_serializing_data__", False)
123
+
119
124
  return target
125
+
126
+ @staticmethod
127
+ def has_attribute(obj: object, attribute_name: str) -> bool:
128
+ """Check if an object has an attribute"""
129
+ try:
130
+ return hasattr(obj, attribute_name)
131
+ except AttributeError:
132
+ return False
133
+ except Exception as e: # pylint: disable=w0718
134
+ raise RuntimeError(
135
+ "Failed to serialize the object. \n"
136
+ "You may have some validation that is preventing this routine "
137
+ "from completing. Such as a None checker on a getter. \n\n"
138
+ "To work around this create a boolean (bool) property named __actively_serializing_data__. \n"
139
+ "e.g. self.__actively_serializing_data__: bool = False\n\n"
140
+ "Only issue/raise your exception if __actively_serializing_data__ is not True. \n\n"
141
+ "e.g. if not self.some_propert and not self.__actively_serializing_data__:\n"
142
+ ' raise ValueError("some_property must be set")\n\n'
143
+ "This procedure will update the property from False to True while serializing, "
144
+ "then back to False once serialization is complete. "
145
+ ) from e
boto3_assist/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.2.9'
1
+ __version__ = '0.2.11'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boto3_assist
3
- Version: 0.2.9
3
+ Version: 0.2.11
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
@@ -2,21 +2,21 @@ boto3_assist/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  boto3_assist/boto3session.py,sha256=NWhWtYR3143thEbTpoklkwdz77-fTMs-QsoQdqfRm6E,6430
3
3
  boto3_assist/connection.py,sha256=EJlGueLIYqMSKs7aQlThK1S0Zkb8dOYBWch1iRZdgUI,3233
4
4
  boto3_assist/connection_tracker.py,sha256=_s1t7h2DOi3CCIHIr_HIKyGjku65WR-HJ_v8vJHDvO0,2977
5
- boto3_assist/version.py,sha256=bd8hlxKMc0Fh_2w5GWfqBtuwa8uTepTMjT8w7F-EKvY,22
5
+ boto3_assist/version.py,sha256=1GoaUwMSeBBLruUDdM6dEOYv-nA5voDZ34P71yo1WKo,23
6
6
  boto3_assist/cloudwatch/cloudwatch_connection.py,sha256=mnGWaLSQpHh5EeY7Ek_2o9JKHJxOELIYtQVMX1IaHn4,2480
7
7
  boto3_assist/cloudwatch/cloudwatch_connection_tracker.py,sha256=mzRtO1uHrcfJNh1XrGEiXdTqxwEP8d1RqJkraMNkgK0,410
8
8
  boto3_assist/cloudwatch/cloudwatch_log_connection.py,sha256=qQMZHjUJ6gA8wU9utjQhOURXNSPH2RjxSoAy83bvoCs,1737
9
9
  boto3_assist/cloudwatch/cloudwatch_logs.py,sha256=VtI0OnFjX1l4RYVvA8tvveGkPwAogtrplnflZ4dQSNM,1204
10
10
  boto3_assist/cloudwatch/cloudwatch_query.py,sha256=uNhSb1Gfp99v8BaHmCnCKs63j4MMU4WveqBavCJyhGY,6409
11
- boto3_assist/dynamodb/dynamodb.py,sha256=PVWALqf5f8ftsf3U5xcNFo_32HQmysgkNbucMwope4w,15771
11
+ boto3_assist/dynamodb/dynamodb.py,sha256=q3U4uYqnKX1_u5TXv8Iq94JrBad16q0rL_vKxQyR_3k,15772
12
12
  boto3_assist/dynamodb/dynamodb_connection.py,sha256=hr4IGbbEE73fh375tj3_XtYAwwDV0s7z1-6JK_1Tc30,5263
13
13
  boto3_assist/dynamodb/dynamodb_connection_tracker.py,sha256=0BWHRfi5_vjkJLuCSX6sYwvA6wc7BSYCQnGrzbhfyKA,404
14
14
  boto3_assist/dynamodb/dynamodb_helpers.py,sha256=ajpTJ5bJOm9PDgE2Zx9p2zkTRFV4xswqJRS81SOTn1s,12198
15
15
  boto3_assist/dynamodb/dynamodb_importer.py,sha256=nCKsyRQeMqDSf0Q5mQ_X_oVIg4PRnu0hcUzZnBli610,3471
16
- boto3_assist/dynamodb/dynamodb_index.py,sha256=7xa2bN3o8P7XIN9CcJiU7_i1MVjZPl6ZPVZqbZr8pS4,7747
16
+ boto3_assist/dynamodb/dynamodb_index.py,sha256=fNIFeuUqjoYN82DcF1FRtkKwb0rXI5KMVeE9BrDLblI,8359
17
17
  boto3_assist/dynamodb/dynamodb_iservice.py,sha256=O9Aj0PFEvcuk2vhARifWTFnUwcQW5EXzwZS478Hm-N0,796
18
18
  boto3_assist/dynamodb/dynamodb_key.py,sha256=YD7o1EUlwVBQ55p9YCTKqAUU_np4nqtLIHnmp-BeolM,1803
19
- boto3_assist/dynamodb/dynamodb_model_base.py,sha256=RpVhh88Bvg0aPO5Ux1yliFc8-INQfWdMsXo3mk_Clw8,15351
19
+ boto3_assist/dynamodb/dynamodb_model_base.py,sha256=bAKYN2h__tGBtYmcNh-Ra-8DHzvnqZpjVeiXaCNYDZA,15408
20
20
  boto3_assist/dynamodb/dynamodb_model_base_interfaces.py,sha256=yT4zDRI8vP15WVOHnCvY3FsEy_QSIta5-bnUby70Xow,747
21
21
  boto3_assist/dynamodb/dynamodb_reindexer.py,sha256=bCj6KIU0fQOgjkkiq9yF51PFZZr4Y9Lu3-hPlmsPG0Y,6164
22
22
  boto3_assist/dynamodb/dynamodb_reserved_words.py,sha256=p0irNBSqGe4rd2FwWQqbRJWrNr4svdbWiyIXmz9lj4c,1937
@@ -34,10 +34,10 @@ boto3_assist/utilities/datetime_utility.py,sha256=TbqGQkJDTahqvaZAIV550nhYnW1Bsq
34
34
  boto3_assist/utilities/file_operations.py,sha256=Zy8fu8fpuVNf7U9NimrLdy5FRF71XSI159cnRdzmzGY,3411
35
35
  boto3_assist/utilities/http_utility.py,sha256=koFv7Va-8ng-47Nt1K2Sh7Ti95e62IYs9VMLlGh9Kt4,1173
36
36
  boto3_assist/utilities/logging_utility.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- boto3_assist/utilities/serialization_utility.py,sha256=s_QQRIhtwIE7xN5nU13mNk2wtWyErBX_Sg7n0gbHj-M,4308
37
+ boto3_assist/utilities/serialization_utility.py,sha256=AWm8s0E62C35Zb9SLfW6DFA05e8sgCVyHwVl67mdu24,5749
38
38
  boto3_assist/utilities/string_utility.py,sha256=w8l063UT3GE48tuJopETyZrjG4CgAzWkyDWMAYMg5Og,7432
39
- boto3_assist-0.2.9.dist-info/METADATA,sha256=i463YtqFRnpN9R6CpO4LNt5Esk0EJW9-XW5uLx1riqM,1707
40
- boto3_assist-0.2.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
- boto3_assist-0.2.9.dist-info/licenses/LICENSE-EXPLAINED.txt,sha256=WFREvTpfTjPjDHpOLADxJpCKpIla3Ht87RUUGii4ODU,606
42
- boto3_assist-0.2.9.dist-info/licenses/LICENSE.txt,sha256=PXDhFWS5L5aOTkVhNvoitHKbAkgxqMI2uUPQyrnXGiI,1105
43
- boto3_assist-0.2.9.dist-info/RECORD,,
39
+ boto3_assist-0.2.11.dist-info/METADATA,sha256=U0W8JPS56y0U06bXqpOB8reCj4Pew8UB50IVP_GM7F8,1708
40
+ boto3_assist-0.2.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
+ boto3_assist-0.2.11.dist-info/licenses/LICENSE-EXPLAINED.txt,sha256=WFREvTpfTjPjDHpOLADxJpCKpIla3Ht87RUUGii4ODU,606
42
+ boto3_assist-0.2.11.dist-info/licenses/LICENSE.txt,sha256=PXDhFWS5L5aOTkVhNvoitHKbAkgxqMI2uUPQyrnXGiI,1105
43
+ boto3_assist-0.2.11.dist-info/RECORD,,