boto3-assist 0.35.0__py3-none-any.whl → 0.37.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 +10 -0
- boto3_assist/connection.py +85 -6
- boto3_assist/connection_pool.py +179 -0
- boto3_assist/dynamodb/__init__.py +9 -0
- boto3_assist/dynamodb/dynamodb.py +215 -168
- boto3_assist/dynamodb/dynamodb_connection.py +2 -0
- boto3_assist/dynamodb/dynamodb_key.py +9 -4
- boto3_assist/s3/__init__.py +9 -0
- boto3_assist/s3/s3.py +43 -0
- boto3_assist/s3/s3_connection.py +2 -0
- boto3_assist/sqs/sqs_connection.py +43 -0
- boto3_assist/version.py +1 -1
- {boto3_assist-0.35.0.dist-info → boto3_assist-0.37.0.dist-info}/METADATA +1 -1
- {boto3_assist-0.35.0.dist-info → boto3_assist-0.37.0.dist-info}/RECORD +17 -14
- {boto3_assist-0.35.0.dist-info → boto3_assist-0.37.0.dist-info}/WHEEL +0 -0
- {boto3_assist-0.35.0.dist-info → boto3_assist-0.37.0.dist-info}/licenses/LICENSE-EXPLAINED.txt +0 -0
- {boto3_assist-0.35.0.dist-info → boto3_assist-0.37.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -35,6 +35,7 @@ class DynamoDBConnection(Connection):
|
|
|
35
35
|
assume_role_arn: Optional[str] = None,
|
|
36
36
|
assume_role_chain: Optional[List[str]] = None,
|
|
37
37
|
assume_role_duration_seconds: Optional[int] = 3600,
|
|
38
|
+
use_connection_pool: bool = False,
|
|
38
39
|
) -> None:
|
|
39
40
|
super().__init__(
|
|
40
41
|
service_name="dynamodb",
|
|
@@ -46,6 +47,7 @@ class DynamoDBConnection(Connection):
|
|
|
46
47
|
assume_role_arn=assume_role_arn,
|
|
47
48
|
assume_role_chain=assume_role_chain,
|
|
48
49
|
assume_role_duration_seconds=assume_role_duration_seconds,
|
|
50
|
+
use_connection_pool=use_connection_pool,
|
|
49
51
|
)
|
|
50
52
|
|
|
51
53
|
self.__dynamodb_client: DynamoDBClient | None = None
|
|
@@ -48,15 +48,15 @@ class DynamoDBKey:
|
|
|
48
48
|
def to_dict(self) -> dict[str, str]:
|
|
49
49
|
"""
|
|
50
50
|
Return a dictionary representation of this key for debugging.
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
Returns:
|
|
53
53
|
Dictionary with attribute name as key and value as the value.
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
Example:
|
|
56
56
|
>>> key = DynamoDBKey(attribute_name="pk", value="user#123")
|
|
57
57
|
>>> key.to_dict()
|
|
58
58
|
{'pk': 'user#123'}
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
>>> # With lambda
|
|
61
61
|
>>> key = DynamoDBKey(attribute_name="pk", value=lambda: "user#456")
|
|
62
62
|
>>> key.to_dict()
|
|
@@ -119,8 +119,13 @@ class DynamoDBKey:
|
|
|
119
119
|
for key, value in key_value_pairs:
|
|
120
120
|
prefix = f"{key}#" if key else ""
|
|
121
121
|
if value is None:
|
|
122
|
-
|
|
122
|
+
# don't add the prefix we may want loose begins with and compound here will break it
|
|
123
|
+
# parts.append(f"{prefix}")
|
|
124
|
+
if len(parts) == 0:
|
|
125
|
+
parts.append(f"{prefix}")
|
|
126
|
+
# exit after the first None
|
|
123
127
|
break
|
|
128
|
+
|
|
124
129
|
elif len(str(value).strip()) == 0:
|
|
125
130
|
parts.append(f"{key}")
|
|
126
131
|
else:
|
boto3_assist/s3/s3.py
CHANGED
|
@@ -26,6 +26,7 @@ class S3(S3Connection):
|
|
|
26
26
|
aws_end_point_url: Optional[str] = None,
|
|
27
27
|
aws_access_key_id: Optional[str] = None,
|
|
28
28
|
aws_secret_access_key: Optional[str] = None,
|
|
29
|
+
use_connection_pool: bool = False,
|
|
29
30
|
) -> None:
|
|
30
31
|
"""_summary_
|
|
31
32
|
|
|
@@ -35,6 +36,7 @@ class S3(S3Connection):
|
|
|
35
36
|
aws_end_point_url (Optional[str], optional): _description_. Defaults to None.
|
|
36
37
|
aws_access_key_id (Optional[str], optional): _description_. Defaults to None.
|
|
37
38
|
aws_secret_access_key (Optional[str], optional): _description_. Defaults to None.
|
|
39
|
+
use_connection_pool (bool, optional): Use connection pooling. Defaults to False.
|
|
38
40
|
"""
|
|
39
41
|
super().__init__(
|
|
40
42
|
aws_profile=aws_profile,
|
|
@@ -42,11 +44,52 @@ class S3(S3Connection):
|
|
|
42
44
|
aws_end_point_url=aws_end_point_url,
|
|
43
45
|
aws_access_key_id=aws_access_key_id,
|
|
44
46
|
aws_secret_access_key=aws_secret_access_key,
|
|
47
|
+
use_connection_pool=use_connection_pool,
|
|
45
48
|
)
|
|
46
49
|
|
|
47
50
|
self.__s3_object: S3Object | None = None
|
|
48
51
|
self.__s3_bucket: S3Bucket | None = None
|
|
49
52
|
|
|
53
|
+
@classmethod
|
|
54
|
+
def from_pool(
|
|
55
|
+
cls,
|
|
56
|
+
aws_profile: Optional[str] = None,
|
|
57
|
+
aws_region: Optional[str] = None,
|
|
58
|
+
aws_end_point_url: Optional[str] = None,
|
|
59
|
+
**kwargs,
|
|
60
|
+
) -> "S3":
|
|
61
|
+
"""
|
|
62
|
+
Create S3 connection using connection pool (recommended for Lambda).
|
|
63
|
+
|
|
64
|
+
This is the recommended pattern for Lambda functions as it reuses
|
|
65
|
+
boto3 sessions across invocations in warm containers.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
aws_profile: AWS profile name (optional)
|
|
69
|
+
aws_region: AWS region (optional)
|
|
70
|
+
aws_end_point_url: Custom endpoint URL (optional, for moto testing)
|
|
71
|
+
**kwargs: Additional S3 parameters
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
S3 instance configured to use connection pool
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
>>> # Recommended pattern for Lambda
|
|
78
|
+
>>> s3 = S3.from_pool()
|
|
79
|
+
>>> s3.object.upload_file(file_path="/tmp/file.txt", bucket="my-bucket", key="file.txt")
|
|
80
|
+
>>>
|
|
81
|
+
>>> # Subsequent calls reuse the same connection
|
|
82
|
+
>>> s3_2 = S3.from_pool()
|
|
83
|
+
>>> assert s3.session is s3_2.session
|
|
84
|
+
"""
|
|
85
|
+
return cls(
|
|
86
|
+
aws_profile=aws_profile,
|
|
87
|
+
aws_region=aws_region,
|
|
88
|
+
aws_end_point_url=aws_end_point_url,
|
|
89
|
+
use_connection_pool=True,
|
|
90
|
+
**kwargs,
|
|
91
|
+
)
|
|
92
|
+
|
|
50
93
|
@property
|
|
51
94
|
def object(self) -> S3Object:
|
|
52
95
|
"""s3 object"""
|
boto3_assist/s3/s3_connection.py
CHANGED
|
@@ -35,6 +35,7 @@ class S3Connection(Connection):
|
|
|
35
35
|
aws_access_key_id: Optional[str] = None,
|
|
36
36
|
aws_secret_access_key: Optional[str] = None,
|
|
37
37
|
signature_version: Optional[str] = None,
|
|
38
|
+
use_connection_pool: bool = False,
|
|
38
39
|
) -> None:
|
|
39
40
|
# Build S3-specific config if signature_version is specified
|
|
40
41
|
config: Optional[Config] = None
|
|
@@ -50,6 +51,7 @@ class S3Connection(Connection):
|
|
|
50
51
|
aws_secret_access_key=aws_secret_access_key,
|
|
51
52
|
aws_end_point_url=aws_end_point_url,
|
|
52
53
|
config=config,
|
|
54
|
+
use_connection_pool=use_connection_pool,
|
|
53
55
|
)
|
|
54
56
|
|
|
55
57
|
self.__client: S3Client | None = None
|
|
@@ -33,6 +33,7 @@ class SQSConnection(Connection):
|
|
|
33
33
|
aws_end_point_url: Optional[str] = None,
|
|
34
34
|
aws_access_key_id: Optional[str] = None,
|
|
35
35
|
aws_secret_access_key: Optional[str] = None,
|
|
36
|
+
use_connection_pool: bool = False,
|
|
36
37
|
) -> None:
|
|
37
38
|
"""
|
|
38
39
|
Initialize SQS connection.
|
|
@@ -43,6 +44,7 @@ class SQSConnection(Connection):
|
|
|
43
44
|
aws_end_point_url: Custom endpoint URL (for LocalStack, etc.)
|
|
44
45
|
aws_access_key_id: AWS access key ID
|
|
45
46
|
aws_secret_access_key: AWS secret access key
|
|
47
|
+
use_connection_pool: Use connection pooling (recommended for Lambda)
|
|
46
48
|
"""
|
|
47
49
|
super().__init__(
|
|
48
50
|
service_name="sqs",
|
|
@@ -51,11 +53,52 @@ class SQSConnection(Connection):
|
|
|
51
53
|
aws_access_key_id=aws_access_key_id,
|
|
52
54
|
aws_secret_access_key=aws_secret_access_key,
|
|
53
55
|
aws_end_point_url=aws_end_point_url,
|
|
56
|
+
use_connection_pool=use_connection_pool,
|
|
54
57
|
)
|
|
55
58
|
|
|
56
59
|
self.__client: SQSClient | None = None
|
|
57
60
|
self.__resource: SQSServiceResource | None = None
|
|
58
61
|
|
|
62
|
+
@classmethod
|
|
63
|
+
def from_pool(
|
|
64
|
+
cls,
|
|
65
|
+
aws_profile: Optional[str] = None,
|
|
66
|
+
aws_region: Optional[str] = None,
|
|
67
|
+
aws_end_point_url: Optional[str] = None,
|
|
68
|
+
**kwargs,
|
|
69
|
+
) -> "SQSConnection":
|
|
70
|
+
"""
|
|
71
|
+
Create SQS connection using connection pool (recommended for Lambda).
|
|
72
|
+
|
|
73
|
+
This is the recommended pattern for Lambda functions as it reuses
|
|
74
|
+
boto3 sessions across invocations in warm containers.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
aws_profile: AWS profile name (optional)
|
|
78
|
+
aws_region: AWS region (optional)
|
|
79
|
+
aws_end_point_url: Custom endpoint URL (optional, for LocalStack/moto)
|
|
80
|
+
**kwargs: Additional SQS parameters
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
SQSConnection instance configured to use connection pool
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
>>> # Recommended pattern for Lambda
|
|
87
|
+
>>> sqs = SQSConnection.from_pool()
|
|
88
|
+
>>> queue = SQSQueue(sqs, queue_url="https://...")
|
|
89
|
+
>>>
|
|
90
|
+
>>> # Subsequent calls reuse the same connection
|
|
91
|
+
>>> sqs2 = SQSConnection.from_pool()
|
|
92
|
+
>>> assert sqs.session is sqs2.session
|
|
93
|
+
"""
|
|
94
|
+
return cls(
|
|
95
|
+
aws_profile=aws_profile,
|
|
96
|
+
aws_region=aws_region,
|
|
97
|
+
aws_end_point_url=aws_end_point_url,
|
|
98
|
+
use_connection_pool=True,
|
|
99
|
+
**kwargs,
|
|
100
|
+
)
|
|
101
|
+
|
|
59
102
|
@property
|
|
60
103
|
def client(self) -> SQSClient:
|
|
61
104
|
"""Get SQS client."""
|
boto3_assist/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.37.0"
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
boto3_assist/__init__.py,sha256=
|
|
1
|
+
boto3_assist/__init__.py,sha256=lS-oHTASzgSd4UyYByxydFm_EQjTCYvIelzkG6pPgY4,231
|
|
2
2
|
boto3_assist/aws_config.py,sha256=evmk_blj498ugptJa8lxIDJOIursxY6mT4joLfEbrl0,6558
|
|
3
3
|
boto3_assist/boto3session.py,sha256=p4FKVSX5A-xNHdpRan8pgMoY4iIywNfwriyTfjQ-zTQ,2967
|
|
4
|
-
boto3_assist/connection.py,sha256=
|
|
4
|
+
boto3_assist/connection.py,sha256=veKhcZJew3hDukSkUgQ84Ow3XbxwVeEPlGj5IBORMtI,8288
|
|
5
|
+
boto3_assist/connection_pool.py,sha256=I4pfZu7PKW7nkz2lWhlUDK6OB8G7a--GjTyBjerD6FE,6053
|
|
5
6
|
boto3_assist/connection_tracker.py,sha256=UgfR9RlvXf3A4ssMr3gDMpw89ka8mSRvJn4M34SzhbU,4378
|
|
6
7
|
boto3_assist/http_status_codes.py,sha256=G0zRSWenwavYKETvDF9tNVUXQz3Ae2gXdBETYbjvJe8,3284
|
|
7
8
|
boto3_assist/role_assumption_mixin.py,sha256=PMUU5yC2FUBjFD1UokVkRY3CPB5zTw85AhIB5BMtbc8,1031
|
|
8
9
|
boto3_assist/session_setup_mixin.py,sha256=X-JQKyyaWNA8Z8kKgf2V2I5vsiLAH8udLTX_xepnsdQ,3140
|
|
9
|
-
boto3_assist/version.py,sha256=
|
|
10
|
+
boto3_assist/version.py,sha256=XBXO7SJLNyshet4jr9-3xk5IGG5EjpIAS0aNB4_SuTk,23
|
|
10
11
|
boto3_assist/aws_lambda/event_info.py,sha256=OkZ4WzuGaHEu_T8sB188KBgShAJhZpWASALKRGBOhMg,14648
|
|
11
12
|
boto3_assist/aws_lambda/mock_context.py,sha256=LPjHP-3YSoY6iPl1kPqJDwSVf1zLNTcukUunDtYcbK0,116
|
|
12
13
|
boto3_assist/cloudwatch/cloudwatch_connection.py,sha256=mnGWaLSQpHh5EeY7Ek_2o9JKHJxOELIYtQVMX1IaHn4,2480
|
|
@@ -19,13 +20,14 @@ boto3_assist/cognito/cognito_connection.py,sha256=deuXR3cNHz0mCYff2k0LfAvK--9Okq
|
|
|
19
20
|
boto3_assist/cognito/cognito_utility.py,sha256=IVZAg58nHG1U7uxe7FsTYpqwwZiwwdIBGiVTZuLCFqg,18417
|
|
20
21
|
boto3_assist/cognito/jwks_cache.py,sha256=1Y9r-YfQ8qrgZN5xYPvjUEEV0vthbdcPdAIaPbZP7kU,373
|
|
21
22
|
boto3_assist/cognito/user.py,sha256=qc44qLx3gwq6q2zMxcPQze1EjeZwy5Kuav93vbe-4WU,820
|
|
22
|
-
boto3_assist/dynamodb/
|
|
23
|
-
boto3_assist/dynamodb/
|
|
23
|
+
boto3_assist/dynamodb/__init__.py,sha256=uuRqUY9FHTwequ3oMq_VcMcmzhpAKG08GSnZPMNge2k,163
|
|
24
|
+
boto3_assist/dynamodb/dynamodb.py,sha256=VHt5keB-N38nbbytT_pyY6P6PmveI5t4xrYVqVM6HR8,49163
|
|
25
|
+
boto3_assist/dynamodb/dynamodb_connection.py,sha256=JtdS7ciJDuB1pLOUM2UKWxqNh2gXJtVIU9KYzV4VN2U,3704
|
|
24
26
|
boto3_assist/dynamodb/dynamodb_helpers.py,sha256=BYJEuXaQVCPbDfbtPswWA_OvV_yC3fVoTtKvIoZeIBc,12092
|
|
25
27
|
boto3_assist/dynamodb/dynamodb_importer.py,sha256=nCKsyRQeMqDSf0Q5mQ_X_oVIg4PRnu0hcUzZnBli610,3471
|
|
26
28
|
boto3_assist/dynamodb/dynamodb_index.py,sha256=2AKxHo8HrRbaxL0ePj7S6ek36_sy5cHkDp5I9wIp8Kw,19797
|
|
27
29
|
boto3_assist/dynamodb/dynamodb_iservice.py,sha256=O9Aj0PFEvcuk2vhARifWTFnUwcQW5EXzwZS478Hm-N0,796
|
|
28
|
-
boto3_assist/dynamodb/dynamodb_key.py,sha256=
|
|
30
|
+
boto3_assist/dynamodb/dynamodb_key.py,sha256=k09E9gXEckQ20oRaIZdhyoJL3I6FUls5ysEgsLd3FP0,4126
|
|
29
31
|
boto3_assist/dynamodb/dynamodb_model_base.py,sha256=gCUG0UKXV9AUcPBlbxJ3Xb8wOS8awrGG7DZpZjgIS58,21291
|
|
30
32
|
boto3_assist/dynamodb/dynamodb_model_base_interfaces.py,sha256=SFw-yK7TDPL4cK52bpn2zMm5G4mX7eYNU7eFytEw0-A,749
|
|
31
33
|
boto3_assist/dynamodb/dynamodb_re_indexer.py,sha256=D9gCGTJMS1R-ovAbqXK9gMbkl7a9zkBwA8_pxOAkHSY,6164
|
|
@@ -42,15 +44,16 @@ boto3_assist/erc/__init__.py,sha256=ZVpE1TayNer4ZFb3t3wlo5LkWD9G-HbYE2DkoQoMI9w,
|
|
|
42
44
|
boto3_assist/erc/ecr_connection.py,sha256=5fbJiouHe2uta4OiN-NKOo3fS2608Zcc01fWBOyPbI4,1370
|
|
43
45
|
boto3_assist/errors/custom_exceptions.py,sha256=QAMW49NbClELVnRd00u4NHfzVtRS3Tc1TrsIMUP9wLw,1041
|
|
44
46
|
boto3_assist/models/serializable_model.py,sha256=ZMrRJRvJWLY8PBSKK_nPCgYKv1qUxDPEVdcADKbIHsI,266
|
|
45
|
-
boto3_assist/s3/
|
|
47
|
+
boto3_assist/s3/__init__.py,sha256=trlSMj2kjpY27qGkuSVXKwSbbvwTaosPznLkD9xYUVo,145
|
|
48
|
+
boto3_assist/s3/s3.py,sha256=rw27qX7vQuZZ5KCenHun9p8K0vHjDNdZVSCdUrrsaLk,3593
|
|
46
49
|
boto3_assist/s3/s3_bucket.py,sha256=GfyBbuI5BWz_ybwU_nDqUZiC0wt24PNt49GKZmb05OY,2018
|
|
47
|
-
boto3_assist/s3/s3_connection.py,sha256=
|
|
50
|
+
boto3_assist/s3/s3_connection.py,sha256=jfoqeEYq4LF7Y9hVutzkPHuLR1oYiPA2k0O4PP1EPnc,2517
|
|
48
51
|
boto3_assist/s3/s3_event_data.py,sha256=Q7QUI1pwkc7g6yZ3IZWMXBIAfsMlPRC7wac2RvrQoA4,4112
|
|
49
52
|
boto3_assist/s3/s3_object.py,sha256=77jZeIUFpQX3cFYGGwRFBvL-peCe54iILnthm-GFjMc,22518
|
|
50
53
|
boto3_assist/securityhub/securityhub.py,sha256=ne-J_v4DaCVZm5YgJa_-LKVomLJQo5Gpw6wleAKSsws,5467
|
|
51
54
|
boto3_assist/securityhub/securityhub_connection.py,sha256=hWfcj9gjS2lNXUObyw4cShtveoqJPIp8kKFuz-fz1J4,1449
|
|
52
55
|
boto3_assist/sqs/__init__.py,sha256=VRuPPit-hSSbumKL2pN5AUtZKr_c9MpLeuqQ5a6wBLk,285
|
|
53
|
-
boto3_assist/sqs/sqs_connection.py,sha256=
|
|
56
|
+
boto3_assist/sqs/sqs_connection.py,sha256=MEDA2KKlpoRiDcCVh_i37CLhA0a5dlNkfuA9voG-Lxs,4011
|
|
54
57
|
boto3_assist/sqs/sqs_queue.py,sha256=sjz2Q4BbJMCO-cxSNM02UxMmgnRfPLFAC3Pt1kiqc14,9542
|
|
55
58
|
boto3_assist/ssm/connection.py,sha256=gYpKn5HsUR3hcRUqJzF5QcTITCk0DReq9KhoE_8-Htg,1370
|
|
56
59
|
boto3_assist/ssm/parameter_store/parameter_store.py,sha256=2ISi-SmR29mESHFH-onJkxPX1aThIgBRojA3ZoNcP9s,3949
|
|
@@ -63,8 +66,8 @@ boto3_assist/utilities/logging_utility.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
|
63
66
|
boto3_assist/utilities/numbers_utility.py,sha256=wzv9d0uXT_2_ZHHio7LBzibwxPqhGpvbq9HinrVn_4A,10160
|
|
64
67
|
boto3_assist/utilities/serialization_utility.py,sha256=m5wRZNeWW9VltQPVNziR27OGKO3MDJm6mFmcDHwN-n4,24479
|
|
65
68
|
boto3_assist/utilities/string_utility.py,sha256=XxUIz19L2LFFTRDAAmdPa8Qhn40u9yO7g4nULFuvg0M,11033
|
|
66
|
-
boto3_assist-0.
|
|
67
|
-
boto3_assist-0.
|
|
68
|
-
boto3_assist-0.
|
|
69
|
-
boto3_assist-0.
|
|
70
|
-
boto3_assist-0.
|
|
69
|
+
boto3_assist-0.37.0.dist-info/METADATA,sha256=ErrRoU35Bb3qt-O7C2jpCEYWJ23DxZxGCKUI1tanF2Y,2879
|
|
70
|
+
boto3_assist-0.37.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
71
|
+
boto3_assist-0.37.0.dist-info/licenses/LICENSE-EXPLAINED.txt,sha256=WFREvTpfTjPjDHpOLADxJpCKpIla3Ht87RUUGii4ODU,606
|
|
72
|
+
boto3_assist-0.37.0.dist-info/licenses/LICENSE.txt,sha256=PXDhFWS5L5aOTkVhNvoitHKbAkgxqMI2uUPQyrnXGiI,1105
|
|
73
|
+
boto3_assist-0.37.0.dist-info/RECORD,,
|
|
File without changes
|
{boto3_assist-0.35.0.dist-info → boto3_assist-0.37.0.dist-info}/licenses/LICENSE-EXPLAINED.txt
RENAMED
|
File without changes
|
|
File without changes
|