boto3-assist 0.1.14__py3-none-any.whl → 0.2.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 -2
- 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/connection.py +101 -0
- boto3_assist/connection_tracker.py +8 -8
- boto3_assist/dynamodb/dynamodb.py +30 -19
- boto3_assist/dynamodb/dynamodb_connection.py +31 -2
- boto3_assist/dynamodb/dynamodb_index.py +27 -0
- boto3_assist/dynamodb/dynamodb_iservice.py +4 -0
- boto3_assist/dynamodb/dynamodb_model_base.py +6 -7
- boto3_assist/dynamodb/dynamodb_reserved_words.py +6 -3
- boto3_assist/dynamodb/dynamodb_reserved_words.txt +0 -1
- boto3_assist/ec2/ec2_connection.py +3 -0
- boto3_assist/environment_services/environment_loader.py +67 -3
- boto3_assist/environment_services/environment_variables.py +4 -0
- boto3_assist/errors/custom_exceptions.py +34 -0
- boto3_assist/s3/s3.py +476 -0
- boto3_assist/s3/s3_connection.py +120 -0
- boto3_assist/utilities/file_operations.py +105 -0
- boto3_assist/utilities/http_utility.py +42 -0
- boto3_assist/version.py +1 -1
- {boto3_assist-0.1.14.dist-info → boto3_assist-0.2.1.dist-info}/METADATA +1 -3
- boto3_assist-0.2.1.dist-info/RECORD +43 -0
- {boto3_assist-0.1.14.dist-info → boto3_assist-0.2.1.dist-info}/WHEEL +1 -1
- boto3_assist-0.1.14.dist-info/RECORD +0 -32
- {boto3_assist-0.1.14.dist-info → boto3_assist-0.2.1.dist-info}/licenses/LICENSE-EXPLAINED.txt +0 -0
- {boto3_assist-0.1.14.dist-info → boto3_assist-0.2.1.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -5,7 +5,7 @@ MIT License. See Project Root for the license information.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import os
|
|
8
|
-
from typing import List, Optional, overload
|
|
8
|
+
from typing import List, Optional, overload, Dict, Any
|
|
9
9
|
|
|
10
10
|
from aws_lambda_powertools import Tracer, Logger
|
|
11
11
|
from boto3.dynamodb.conditions import (
|
|
@@ -77,7 +77,7 @@ class DynamoDB(DynamoDBConnection):
|
|
|
77
77
|
dict: The Response from DynamoDB's put_item actions.
|
|
78
78
|
It does not return the saved object, only the response.
|
|
79
79
|
"""
|
|
80
|
-
response =
|
|
80
|
+
response: Dict[str, Any] = {}
|
|
81
81
|
|
|
82
82
|
try:
|
|
83
83
|
if not isinstance(item, dict):
|
|
@@ -93,13 +93,13 @@ class DynamoDB(DynamoDBConnection):
|
|
|
93
93
|
|
|
94
94
|
if isinstance(item, dict) and isinstance(next(iter(item.values())), dict):
|
|
95
95
|
# Use boto3.client syntax
|
|
96
|
-
response =
|
|
97
|
-
TableName=table_name, Item=item
|
|
96
|
+
response = dict(
|
|
97
|
+
self.dynamodb_client.put_item(TableName=table_name, Item=item)
|
|
98
98
|
)
|
|
99
99
|
else:
|
|
100
100
|
# Use boto3.resource syntax
|
|
101
101
|
table = self.dynamodb_resource.Table(table_name)
|
|
102
|
-
response = table.put_item(Item=item)
|
|
102
|
+
response = dict(table.put_item(Item=item)) # type: ignore[arg-type]
|
|
103
103
|
|
|
104
104
|
except Exception as e: # pylint: disable=w0718
|
|
105
105
|
logger.exception(
|
|
@@ -117,7 +117,7 @@ class DynamoDB(DynamoDBConnection):
|
|
|
117
117
|
|
|
118
118
|
if self.log_dynamodb_item_size:
|
|
119
119
|
size_bytes: int = StringUtility.get_size_in_bytes(item)
|
|
120
|
-
size_kb:
|
|
120
|
+
size_kb: float = StringUtility.get_size_in_kb(item)
|
|
121
121
|
logger.info({"item_size": {"bytes": size_bytes, "kb": f"{size_kb:.2f}kb"}})
|
|
122
122
|
|
|
123
123
|
if size_kb > 390:
|
|
@@ -144,7 +144,7 @@ class DynamoDB(DynamoDBConnection):
|
|
|
144
144
|
expression_attribute_names: Optional[dict] = None,
|
|
145
145
|
source: Optional[str] = None,
|
|
146
146
|
call_type: str = "resource",
|
|
147
|
-
) ->
|
|
147
|
+
) -> Dict[str, Any]: ...
|
|
148
148
|
|
|
149
149
|
@overload
|
|
150
150
|
def get(
|
|
@@ -158,7 +158,7 @@ class DynamoDB(DynamoDBConnection):
|
|
|
158
158
|
expression_attribute_names: Optional[dict] = None,
|
|
159
159
|
source: Optional[str] = None,
|
|
160
160
|
call_type: str = "resource",
|
|
161
|
-
) ->
|
|
161
|
+
) -> Dict[str, Any]: ...
|
|
162
162
|
|
|
163
163
|
@tracer.capture_method
|
|
164
164
|
def get(
|
|
@@ -173,7 +173,7 @@ class DynamoDB(DynamoDBConnection):
|
|
|
173
173
|
expression_attribute_names: Optional[dict] = None,
|
|
174
174
|
source: Optional[str] = None,
|
|
175
175
|
call_type: str = "resource",
|
|
176
|
-
) ->
|
|
176
|
+
) -> Dict[str, Any]:
|
|
177
177
|
"""
|
|
178
178
|
Description:
|
|
179
179
|
generic get_item dynamoDb call
|
|
@@ -186,12 +186,15 @@ class DynamoDB(DynamoDBConnection):
|
|
|
186
186
|
if table_name is None:
|
|
187
187
|
raise ValueError("table_name must be provided when model is used.")
|
|
188
188
|
if key is not None:
|
|
189
|
-
raise ValueError(
|
|
189
|
+
raise ValueError(
|
|
190
|
+
"key cannot be provided when model is used. "
|
|
191
|
+
"When using the model, we'll automatically use the key defined."
|
|
192
|
+
)
|
|
190
193
|
key = model.indexes.primary.key()
|
|
191
194
|
if do_projections:
|
|
192
195
|
projection_expression = model.projection_expression
|
|
193
196
|
expression_attribute_names = model.projection_expression_attribute_names
|
|
194
|
-
elif key is None
|
|
197
|
+
elif key is None and model is None:
|
|
195
198
|
raise ValueError("Either 'key' or 'model' must be provided.")
|
|
196
199
|
|
|
197
200
|
response = None
|
|
@@ -205,12 +208,18 @@ class DynamoDB(DynamoDBConnection):
|
|
|
205
208
|
# only pass in args that aren't none
|
|
206
209
|
valid_kwargs = {k: v for k, v in kwargs.items() if v is not None}
|
|
207
210
|
|
|
211
|
+
if table_name is None:
|
|
212
|
+
raise ValueError("table_name must be provided.")
|
|
208
213
|
if call_type == "resource":
|
|
209
214
|
table = self.dynamodb_resource.Table(table_name)
|
|
210
|
-
response = table.get_item(Key=key, **valid_kwargs)
|
|
215
|
+
response = dict(table.get_item(Key=key, **valid_kwargs)) # type: ignore[arg-type]
|
|
211
216
|
elif call_type == "client":
|
|
212
|
-
response =
|
|
213
|
-
|
|
217
|
+
response = dict(
|
|
218
|
+
self.dynamodb_client.get_item(
|
|
219
|
+
Key=key,
|
|
220
|
+
TableName=table_name,
|
|
221
|
+
**valid_kwargs, # type: ignore[arg-type]
|
|
222
|
+
)
|
|
214
223
|
)
|
|
215
224
|
else:
|
|
216
225
|
raise ValueError(
|
|
@@ -246,10 +255,12 @@ class DynamoDB(DynamoDBConnection):
|
|
|
246
255
|
dict: dynamodb response dictionary
|
|
247
256
|
"""
|
|
248
257
|
table = self.dynamodb_resource.Table(table_name)
|
|
249
|
-
response =
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
258
|
+
response = dict(
|
|
259
|
+
table.update_item(
|
|
260
|
+
Key=key,
|
|
261
|
+
UpdateExpression=update_expression,
|
|
262
|
+
ExpressionAttributeValues=expression_attribute_values,
|
|
263
|
+
)
|
|
253
264
|
)
|
|
254
265
|
|
|
255
266
|
return response
|
|
@@ -307,7 +318,7 @@ class DynamoDB(DynamoDBConnection):
|
|
|
307
318
|
raise ValueError("Query failed: table_name must be provided.")
|
|
308
319
|
|
|
309
320
|
table = self.dynamodb_resource.Table(table_name)
|
|
310
|
-
response = table.query(**kwargs)
|
|
321
|
+
response = dict(table.query(**kwargs))
|
|
311
322
|
|
|
312
323
|
return response
|
|
313
324
|
|
|
@@ -92,10 +92,13 @@ class DynamoDBConnection:
|
|
|
92
92
|
"""Session"""
|
|
93
93
|
if self.__session is None:
|
|
94
94
|
self.setup(setup_source="session init")
|
|
95
|
+
|
|
96
|
+
if self.__session is None:
|
|
97
|
+
raise RuntimeError("Session is not available")
|
|
95
98
|
return self.__session
|
|
96
99
|
|
|
97
100
|
@property
|
|
98
|
-
def
|
|
101
|
+
def client(self) -> DynamoDBClient:
|
|
99
102
|
"""DynamoDB Client Connection"""
|
|
100
103
|
if self.__dynamodb_client is None:
|
|
101
104
|
logger.info("Creating DynamoDB Client")
|
|
@@ -105,13 +108,26 @@ class DynamoDBConnection:
|
|
|
105
108
|
raise RuntimeError("DynamoDB Client is not available")
|
|
106
109
|
return self.__dynamodb_client
|
|
107
110
|
|
|
111
|
+
@client.setter
|
|
112
|
+
def client(self, value: DynamoDBClient):
|
|
113
|
+
logger.info("Setting DynamoDB Client")
|
|
114
|
+
self.__dynamodb_client = value
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def dynamodb_client(self) -> DynamoDBClient:
|
|
118
|
+
"""
|
|
119
|
+
DynamoDB Client Connection
|
|
120
|
+
- Backward Compatible. You should use client instead
|
|
121
|
+
"""
|
|
122
|
+
return self.client
|
|
123
|
+
|
|
108
124
|
@dynamodb_client.setter
|
|
109
125
|
def dynamodb_client(self, value: DynamoDBClient):
|
|
110
126
|
logger.info("Setting DynamoDB Client")
|
|
111
127
|
self.__dynamodb_client = value
|
|
112
128
|
|
|
113
129
|
@property
|
|
114
|
-
def
|
|
130
|
+
def resource(self) -> DynamoDBServiceResource:
|
|
115
131
|
"""DynamoDB Resource Connection"""
|
|
116
132
|
if self.__dynamodb_resource is None:
|
|
117
133
|
logger.info("Creating DynamoDB Resource")
|
|
@@ -122,6 +138,19 @@ class DynamoDBConnection:
|
|
|
122
138
|
|
|
123
139
|
return self.__dynamodb_resource
|
|
124
140
|
|
|
141
|
+
@resource.setter
|
|
142
|
+
def resource(self, value: DynamoDBServiceResource):
|
|
143
|
+
logger.info("Setting DynamoDB Resource")
|
|
144
|
+
self.__dynamodb_resource = value
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def dynamodb_resource(self) -> DynamoDBServiceResource:
|
|
148
|
+
"""
|
|
149
|
+
DynamoDB Resource Connection
|
|
150
|
+
- Backward Compatible. You should use resource instead
|
|
151
|
+
"""
|
|
152
|
+
return self.resource
|
|
153
|
+
|
|
125
154
|
@dynamodb_resource.setter
|
|
126
155
|
def dynamodb_resource(self, value: DynamoDBServiceResource):
|
|
127
156
|
logger.info("Setting DynamoDB Resource")
|
|
@@ -34,6 +34,33 @@ class DynamoDBIndexes:
|
|
|
34
34
|
"""Add a GSI/LSI index"""
|
|
35
35
|
if index.name is None:
|
|
36
36
|
raise ValueError("Index name cannot be None")
|
|
37
|
+
|
|
38
|
+
# if the index already exists, raise an exception
|
|
39
|
+
if index.name in self.__indexes:
|
|
40
|
+
raise ValueError(f"Index {index.name} already exists")
|
|
41
|
+
if index.name == DynamoDBIndexes.PRIMARY_INDEX:
|
|
42
|
+
raise ValueError(f"Index {index.name} is reserved for the primary index")
|
|
43
|
+
if index.partition_key is None:
|
|
44
|
+
raise ValueError("Index must have a partition key")
|
|
45
|
+
|
|
46
|
+
# check if the index.partition_key.attribute_name is already in the index
|
|
47
|
+
for _, v in self.__indexes.items():
|
|
48
|
+
if v.partition_key.attribute_name == index.partition_key.attribute_name:
|
|
49
|
+
raise ValueError(
|
|
50
|
+
f"The attrubute {index.partition_key.attribute_name} is already being used by index "
|
|
51
|
+
f"{v.name}. "
|
|
52
|
+
f"Reusing this attribute would over write the value on index {v.name}"
|
|
53
|
+
)
|
|
54
|
+
# check if the gsi1.sort_key.attribute_name exists
|
|
55
|
+
if index.sort_key is not None:
|
|
56
|
+
for _, v in self.__indexes.items():
|
|
57
|
+
if v.sort_key.attribute_name == index.sort_key.attribute_name:
|
|
58
|
+
raise ValueError(
|
|
59
|
+
f"The attrubute {index.sort_key.attribute_name} is already being used by index "
|
|
60
|
+
f"{v.name}. "
|
|
61
|
+
f"Reusing this attribute would over write the value on index {v.name}"
|
|
62
|
+
)
|
|
63
|
+
|
|
37
64
|
self.__indexes[index.name] = index
|
|
38
65
|
|
|
39
66
|
def get(self, index_name: str) -> DynamoDBIndex:
|
|
@@ -7,6 +7,10 @@ from boto3_assist.dynamodb.dynamodb_model_base import DynamoDBModelBase
|
|
|
7
7
|
class IDynamoDBService(ABC):
|
|
8
8
|
"""DynamoDB Service Interface"""
|
|
9
9
|
|
|
10
|
+
def __init__(self, db: DynamoDB) -> None:
|
|
11
|
+
self.db = db
|
|
12
|
+
super().__init__()
|
|
13
|
+
|
|
10
14
|
@property
|
|
11
15
|
@abstractmethod
|
|
12
16
|
def db(self) -> DynamoDB:
|
|
@@ -9,8 +9,7 @@ import datetime as dt
|
|
|
9
9
|
import decimal
|
|
10
10
|
import inspect
|
|
11
11
|
import uuid
|
|
12
|
-
|
|
13
|
-
from typing import TypeVar, List
|
|
12
|
+
from typing import TypeVar, List, Dict, Any
|
|
14
13
|
from boto3.dynamodb.types import TypeSerializer
|
|
15
14
|
from boto3_assist.utilities.serialization_utility import Serialization
|
|
16
15
|
from boto3_assist.dynamodb.dynamodb_helpers import DynamoDBHelpers
|
|
@@ -82,6 +81,10 @@ class DynamoDBModelBase:
|
|
|
82
81
|
|
|
83
82
|
return self.__projection_expression
|
|
84
83
|
|
|
84
|
+
@projection_expression.setter
|
|
85
|
+
def projection_expression(self, value: str | None):
|
|
86
|
+
self.__projection_expression = value
|
|
87
|
+
|
|
85
88
|
@property
|
|
86
89
|
@exclude_from_serialization
|
|
87
90
|
def auto_generate_projections(self) -> bool:
|
|
@@ -92,10 +95,6 @@ class DynamoDBModelBase:
|
|
|
92
95
|
def auto_generate_projections(self, value: bool):
|
|
93
96
|
self.__auto_generate_projections = value
|
|
94
97
|
|
|
95
|
-
@projection_expression.setter
|
|
96
|
-
def projection_expression(self, value: str | None):
|
|
97
|
-
self.__projection_expression = value
|
|
98
|
-
|
|
99
98
|
@property
|
|
100
99
|
@exclude_from_serialization
|
|
101
100
|
def projection_expression_attribute_names(self) -> dict | None:
|
|
@@ -126,7 +125,7 @@ class DynamoDBModelBase:
|
|
|
126
125
|
def projection_expression_attribute_names(self, value: dict | None):
|
|
127
126
|
self.__projection_expression_attribute_names = value
|
|
128
127
|
|
|
129
|
-
def map(self: T, item:
|
|
128
|
+
def map(self: T, item: Dict[str, Any] | DynamoDBModelBase | None) -> T | None:
|
|
130
129
|
"""
|
|
131
130
|
Map the item to the instance. If the item is a DynamoDBModelBase,
|
|
132
131
|
it will be converted to a dictionary first and then mapped.
|
|
@@ -3,7 +3,10 @@ from typing import List
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class DynamoDBReservedWords:
|
|
6
|
-
"""
|
|
6
|
+
"""
|
|
7
|
+
Reserved Words used by DynamoDB that can cause issues,
|
|
8
|
+
so they will need to be transformed under certain conditions, such as when doing projections
|
|
9
|
+
"""
|
|
7
10
|
|
|
8
11
|
def __init__(self) -> None:
|
|
9
12
|
self.__list: List[str] = self.__read_list()
|
|
@@ -35,9 +38,9 @@ class DynamoDBReservedWords:
|
|
|
35
38
|
projections = ["#" + p if self.is_reserved_word(p) else p for p in projections]
|
|
36
39
|
return projections
|
|
37
40
|
|
|
38
|
-
def transform_attributes(self, projections: List[str] | str) -> dict:
|
|
41
|
+
def transform_attributes(self, projections: List[str] | str) -> dict | None:
|
|
39
42
|
"""Transforms a dict of attributes to remove reserved words"""
|
|
40
|
-
transformed_attributes: dict
|
|
43
|
+
transformed_attributes: dict = {}
|
|
41
44
|
if isinstance(projections, str):
|
|
42
45
|
projections = projections.split(",")
|
|
43
46
|
for item in projections:
|
|
@@ -1,22 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geek Cafe, LLC
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for the license information.
|
|
5
|
+
"""
|
|
6
|
+
|
|
1
7
|
import os
|
|
2
|
-
|
|
8
|
+
|
|
9
|
+
from typing import List, Union, Optional, IO
|
|
10
|
+
from pathlib import Path
|
|
3
11
|
from dotenv import load_dotenv
|
|
12
|
+
from aws_lambda_powertools import Logger
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
logger = Logger(__name__)
|
|
16
|
+
|
|
17
|
+
DEBUGGING = os.getenv("DEBUGGING", "false").lower() == "true"
|
|
4
18
|
|
|
5
19
|
StrPath = Union[str, "os.PathLike[str]"]
|
|
6
20
|
|
|
7
21
|
|
|
8
22
|
class EnvironmentLoader:
|
|
23
|
+
"""Environment Loader"""
|
|
24
|
+
|
|
9
25
|
def __init__(self) -> None:
|
|
10
26
|
pass
|
|
11
27
|
|
|
12
28
|
def load_environment_file(
|
|
13
29
|
self,
|
|
30
|
+
*,
|
|
31
|
+
starting_path: Optional[str] = None,
|
|
32
|
+
file_name: Optional[str] = None,
|
|
14
33
|
path: Optional[StrPath] = None,
|
|
15
34
|
stream: Optional[IO[str]] = None,
|
|
16
35
|
verbose: bool = False,
|
|
17
36
|
override: bool = True,
|
|
18
37
|
interpolate: bool = True,
|
|
19
38
|
encoding: Optional[str] = "utf-8",
|
|
39
|
+
raise_error_if_not_found: bool = False,
|
|
20
40
|
) -> bool:
|
|
21
41
|
"""
|
|
22
42
|
Loads an environment file into memory. This simply passes off to load_dotenv in dotenv.
|
|
@@ -37,11 +57,55 @@ class EnvironmentLoader:
|
|
|
37
57
|
If both `dotenv_path` and `stream` are `None`, `find_dotenv()` is used to find the
|
|
38
58
|
.env file.
|
|
39
59
|
"""
|
|
40
|
-
|
|
41
|
-
|
|
60
|
+
|
|
61
|
+
if not starting_path:
|
|
62
|
+
starting_path = __file__
|
|
63
|
+
|
|
64
|
+
if file_name is None:
|
|
65
|
+
file_name = ".env"
|
|
66
|
+
|
|
67
|
+
new_path: str | StrPath | None = path or self.find_file(
|
|
68
|
+
starting_path=starting_path,
|
|
69
|
+
file_name=file_name,
|
|
70
|
+
raise_error_if_not_found=raise_error_if_not_found,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
loaded = load_dotenv(
|
|
74
|
+
dotenv_path=new_path,
|
|
42
75
|
stream=stream,
|
|
43
76
|
verbose=verbose,
|
|
44
77
|
override=override,
|
|
45
78
|
interpolate=interpolate,
|
|
46
79
|
encoding=encoding,
|
|
47
80
|
)
|
|
81
|
+
|
|
82
|
+
if DEBUGGING:
|
|
83
|
+
env_vars = os.environ
|
|
84
|
+
logger.debug(f"Loaded environment file: {path}")
|
|
85
|
+
print(env_vars)
|
|
86
|
+
|
|
87
|
+
return loaded
|
|
88
|
+
|
|
89
|
+
def find_file(
|
|
90
|
+
self, starting_path: str, file_name: str, raise_error_if_not_found: bool = True
|
|
91
|
+
) -> str | None:
|
|
92
|
+
"""Searches the project directory structor for a file"""
|
|
93
|
+
parents = 10
|
|
94
|
+
starting_path = starting_path or __file__
|
|
95
|
+
|
|
96
|
+
paths: List[str] = []
|
|
97
|
+
for parent in range(parents):
|
|
98
|
+
path = Path(starting_path).parents[parent].absolute()
|
|
99
|
+
print(f"searching: {path}")
|
|
100
|
+
tmp = os.path.join(path, file_name)
|
|
101
|
+
paths.append(tmp)
|
|
102
|
+
if os.path.exists(tmp):
|
|
103
|
+
return tmp
|
|
104
|
+
|
|
105
|
+
if raise_error_if_not_found:
|
|
106
|
+
searched_paths = "\n".join(paths)
|
|
107
|
+
raise RuntimeError(
|
|
108
|
+
f"Failed to locate environment file: {file_name} in: \n {searched_paths}"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
return None
|
|
@@ -27,6 +27,8 @@ class EnvironmentVariables:
|
|
|
27
27
|
gets the aws region from an environment var
|
|
28
28
|
"""
|
|
29
29
|
value = os.getenv("AWS_REGION")
|
|
30
|
+
if not value:
|
|
31
|
+
value = None
|
|
30
32
|
return value
|
|
31
33
|
|
|
32
34
|
@staticmethod
|
|
@@ -36,6 +38,8 @@ class EnvironmentVariables:
|
|
|
36
38
|
This should only be set with temporty creds and only for development purposes
|
|
37
39
|
"""
|
|
38
40
|
value = os.getenv("AWS_PROFILE")
|
|
41
|
+
if not value:
|
|
42
|
+
value = None
|
|
39
43
|
return value
|
|
40
44
|
|
|
41
45
|
@staticmethod
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class Error(Exception):
|
|
2
|
+
"""Base class for exceptions in this module."""
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DbFailures(Error):
|
|
6
|
+
"""DB Failure Error"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class InvalidHttpMethod(Exception):
|
|
10
|
+
"""Invalid Http Method"""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
code=422,
|
|
15
|
+
message="Invalid Http Method",
|
|
16
|
+
):
|
|
17
|
+
"""The user account is not valid"""
|
|
18
|
+
self.message = {
|
|
19
|
+
"status_code": code,
|
|
20
|
+
"message": message,
|
|
21
|
+
}
|
|
22
|
+
super().__init__(self.message)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class InvalidRoutePath(Exception):
|
|
26
|
+
"""Invalid Http Route"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, message="Invalid Route"):
|
|
29
|
+
"""Invalid Route"""
|
|
30
|
+
self.message = {
|
|
31
|
+
"status_code": 404,
|
|
32
|
+
"message": message,
|
|
33
|
+
}
|
|
34
|
+
super().__init__(self.message)
|