reach_commons 0.17.1__py3-none-any.whl → 0.17.2__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.
reach_commons/reach_aws/s3.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from functools import cached_property
|
|
2
2
|
from io import BytesIO
|
|
3
|
+
from urllib.parse import unquote, urlparse
|
|
3
4
|
|
|
4
5
|
import boto3
|
|
5
6
|
|
|
@@ -25,13 +26,48 @@ class S3Client:
|
|
|
25
26
|
|
|
26
27
|
return session.client("s3")
|
|
27
28
|
|
|
29
|
+
def _parse_s3_url(self, url: str) -> tuple[str, str]:
|
|
30
|
+
"""
|
|
31
|
+
Support various S3 URL formats:
|
|
32
|
+
- s3://bucket/key
|
|
33
|
+
- https://bucket.s3.amazonaws.com/key
|
|
34
|
+
- https://bucket.s3.<region>.amazonaws.com/key
|
|
35
|
+
- https://s3.<region>.amazonaws.com/bucket/key (path-style)
|
|
36
|
+
- https://s3.amazonaws.com/bucket/key (path-style)
|
|
37
|
+
"""
|
|
38
|
+
p = urlparse(url)
|
|
39
|
+
|
|
40
|
+
if p.scheme == "s3":
|
|
41
|
+
bucket = p.netloc
|
|
42
|
+
key = p.path.lstrip("/")
|
|
43
|
+
return bucket, unquote(key)
|
|
44
|
+
|
|
45
|
+
host = p.netloc
|
|
46
|
+
path = p.path.lstrip("/")
|
|
47
|
+
|
|
48
|
+
# Path-style: s3.<region>.amazonaws.com/bucket/key ou s3.amazonaws.com/bucket/key
|
|
49
|
+
if host.startswith("s3.") or host == "s3.amazonaws.com":
|
|
50
|
+
parts = path.split("/", 1)
|
|
51
|
+
if not parts or not parts[0]:
|
|
52
|
+
raise ValueError(f"Invalid S3 URL (missing bucket in path): {url}")
|
|
53
|
+
bucket = parts[0]
|
|
54
|
+
key = parts[1] if len(parts) > 1 else ""
|
|
55
|
+
return bucket, unquote(key)
|
|
56
|
+
|
|
57
|
+
# Virtual-hosted: bucket.s3[.<region>].amazonaws.com/key
|
|
58
|
+
bucket = host.split(".")[0]
|
|
59
|
+
key = path
|
|
60
|
+
if not bucket:
|
|
61
|
+
raise ValueError(f"Invalid S3 URL (missing bucket in host): {url}")
|
|
62
|
+
return bucket, unquote(key)
|
|
63
|
+
|
|
28
64
|
def get_object(self, s3_bucket_name, s3_key):
|
|
29
65
|
try:
|
|
30
66
|
s3_object = self.client.get_object(Bucket=s3_bucket_name, Key=s3_key)
|
|
31
67
|
actual_message_body = s3_object["Body"].read().decode("utf-8")
|
|
32
68
|
|
|
33
69
|
self.logger.info(
|
|
34
|
-
f"Retrieved object from S3: {s3_key}
|
|
70
|
+
f"Retrieved object from S3: {s3_key} in bucket: {s3_bucket_name}"
|
|
35
71
|
)
|
|
36
72
|
return actual_message_body
|
|
37
73
|
except Exception as e:
|
|
@@ -61,3 +97,17 @@ class S3Client:
|
|
|
61
97
|
f"Error uploading object {s3_key} to bucket: {s3_bucket_name}: {str(e)}"
|
|
62
98
|
)
|
|
63
99
|
return None
|
|
100
|
+
|
|
101
|
+
def delete_object_by_url(self, url: str) -> bool:
|
|
102
|
+
"""
|
|
103
|
+
Deleta um objeto no S3 recebendo apenas a URL direta.
|
|
104
|
+
Retorna True se deletou (ou o objeto não existia) e False se falhou.
|
|
105
|
+
"""
|
|
106
|
+
try:
|
|
107
|
+
bucket, key = self._parse_s3_url(url)
|
|
108
|
+
self.client.delete_object(Bucket=bucket, Key=key)
|
|
109
|
+
self.logger.info(f"Deleted object from S3: {key} in bucket: {bucket}")
|
|
110
|
+
return True
|
|
111
|
+
except Exception as e:
|
|
112
|
+
self.logger.error(f"Error deleting S3 object from url '{url}': {e}")
|
|
113
|
+
return False
|
|
@@ -20,13 +20,13 @@ reach_commons/reach_aws/dynamo_db.py,sha256=ndwLlaDwb96IlsnpAeeKPg-2DOjxe0JSM0y-
|
|
|
20
20
|
reach_commons/reach_aws/exceptions.py,sha256=x0RL5ktNtzxg0KykhEVWReBq_dEtciK6B2vMs_s4C9k,915
|
|
21
21
|
reach_commons/reach_aws/firehose.py,sha256=1xFKLWMv3bNo3PPW5gtaL6NqzUDyVil6B768slj2wbY,5674
|
|
22
22
|
reach_commons/reach_aws/kms.py,sha256=HDJ3lnKm6Jah2asizUDtQErlVSjrcV9lOfBPHzUVguY,4526
|
|
23
|
-
reach_commons/reach_aws/s3.py,sha256=
|
|
23
|
+
reach_commons/reach_aws/s3.py,sha256=2MLlDNFx0SROJBpE_KjJefyrB7lMqTlrYuRhSZx4iKs,3945
|
|
24
24
|
reach_commons/reach_aws/sqs.py,sha256=LKQ42vRJko2HTE8gO_lRvftnstIMI3DeFZakvLUM0BQ,15864
|
|
25
25
|
reach_commons/reach_base_model.py,sha256=uMmDGjwKTZ3h7f8Pfvc99FCsAt5eZNlUJnLLbB5EqGY,2907
|
|
26
26
|
reach_commons/redis_manager.py,sha256=tK-kBw1fO1f-phsxGI-7W_MEtHQsRz7JY9LEN8OBcNY,2600
|
|
27
27
|
reach_commons/sms_smart_encoding.py,sha256=92y0RmZ0l4ONHpC9qeO5KfViSNq64yE2rc7lhNDSZqE,1241
|
|
28
28
|
reach_commons/utils.py,sha256=dMgKIGqTgoSItuBI8oz81gKtW3qi21Jkljv9leS_V88,8475
|
|
29
29
|
reach_commons/validations.py,sha256=jc78boM62S9Z0Ip_nV1z7I983gGpW2Y7vOCQtmia8OU,964
|
|
30
|
-
reach_commons-0.17.
|
|
31
|
-
reach_commons-0.17.
|
|
32
|
-
reach_commons-0.17.
|
|
30
|
+
reach_commons-0.17.2.dist-info/METADATA,sha256=Nv9Yt30sd6GapsZMFcbImBAkmAeXC_u1waKmHlsh5o8,1860
|
|
31
|
+
reach_commons-0.17.2.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
32
|
+
reach_commons-0.17.2.dist-info/RECORD,,
|
|
File without changes
|