pyaws-s3 1.0.23__tar.gz → 1.0.27__tar.gz
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.
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/PKG-INFO +1 -1
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/pyaws_s3/s3.py +121 -30
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/pyaws_s3.egg-info/PKG-INFO +1 -1
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/pyproject.toml +1 -1
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/LICENSE.md +0 -0
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/README.md +0 -0
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/pyaws_s3/__init__.py +0 -0
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/pyaws_s3.egg-info/SOURCES.txt +0 -0
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/pyaws_s3.egg-info/dependency_links.txt +0 -0
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/pyaws_s3.egg-info/requires.txt +0 -0
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/pyaws_s3.egg-info/top_level.txt +0 -0
- {pyaws_s3-1.0.23 → pyaws_s3-1.0.27}/setup.cfg +0 -0
@@ -42,6 +42,25 @@ class S3Client:
|
|
42
42
|
self.region_name = kwargs.get("region_name", os.getenv("AWS_REGION"))
|
43
43
|
self.bucket_name = kwargs.get("bucket_name", os.getenv("AWS_BUCKET_NAME"))
|
44
44
|
|
45
|
+
# crea una funzione per verifica la presenza di un file nel bucket
|
46
|
+
def file_exists(self, object_name: str) -> bool:
|
47
|
+
"""
|
48
|
+
Check if a file exists in the S3 bucket.
|
49
|
+
|
50
|
+
Args:
|
51
|
+
object_name (str): The name of the S3 object to check.
|
52
|
+
|
53
|
+
Returns:
|
54
|
+
bool: True if the file exists, False otherwise.
|
55
|
+
"""
|
56
|
+
s3_client = self._get_s3_client()
|
57
|
+
try:
|
58
|
+
s3_client.head_object(Bucket=self.bucket_name, Key=object_name)
|
59
|
+
return True
|
60
|
+
except Exception as e:
|
61
|
+
logger.error(f"Error checking file existence: {str(e)}")
|
62
|
+
return False
|
63
|
+
|
45
64
|
def _bytes_from_figure(self, f: Figure, **kwargs) -> bytes:
|
46
65
|
"""
|
47
66
|
Convert a Plotly Figure to a PNG image as bytes.
|
@@ -173,23 +192,24 @@ class S3Client:
|
|
173
192
|
|
174
193
|
return temp_url
|
175
194
|
|
176
|
-
def upload_bytes(self, *args, **kwargs: Any):
|
195
|
+
def upload_bytes(self, *args, **kwargs: Any) -> tuple[str, bool]:
|
177
196
|
"""
|
178
197
|
Upload a Plotly Figure as a PNG image to an S3 bucket and generate a pre-signed URL.
|
179
198
|
|
180
199
|
Args:
|
181
|
-
|
182
|
-
bucket_name (str): The name of the S3 bucket.
|
200
|
+
bytes_data (bytes): The bytes data of the image to upload.
|
183
201
|
object_name (str): The name of the S3 object.
|
202
|
+
format_file (str): Format of the image. Defaults to 'pdf' ["png", "jpeg", "svg", "html", "pdf"].
|
203
|
+
overwrite (bool): If True, overwrite the existing file in S3. Defaults to False.
|
204
|
+
presigned_url (bool): If True, generate a pre-signed URL for the uploaded image. Defaults to False.
|
205
|
+
Raises:
|
206
|
+
Exception: If there is an error uploading the image.
|
184
207
|
|
185
208
|
Keyword Args:
|
186
209
|
format_file (str): Format of the image. Defaults to 'png'.
|
187
210
|
|
188
211
|
Returns:
|
189
212
|
str: Pre-signed URL for the uploaded image.
|
190
|
-
|
191
|
-
Raises:
|
192
|
-
Exception: If there is an error uploading the image.
|
193
213
|
"""
|
194
214
|
try:
|
195
215
|
|
@@ -199,6 +219,9 @@ class S3Client:
|
|
199
219
|
else:
|
200
220
|
bytes_data = kwargs.get("bytes_data", None)
|
201
221
|
object_name = kwargs.get("object_name", None)
|
222
|
+
|
223
|
+
overwrite = kwargs.get("overwrite", False)
|
224
|
+
presigned_url = kwargs.get("presigned_url", False)
|
202
225
|
|
203
226
|
if bytes_data is None:
|
204
227
|
raise Exception("Figure is None")
|
@@ -209,6 +232,16 @@ class S3Client:
|
|
209
232
|
format_file : FormatFile = kwargs.get("format_file", "pdf")
|
210
233
|
mimetypes = "application/pdf"
|
211
234
|
|
235
|
+
# Get S3 client and resource
|
236
|
+
s3_client = self._get_s3_client()
|
237
|
+
s3_resource = self._get_s3_resource()
|
238
|
+
|
239
|
+
if not overwrite and self.file_exists(object_name):
|
240
|
+
print(f"File {object_name} already exists in the bucket {self.bucket_name}. Use overwrite=True to overwrite it.")
|
241
|
+
if presigned_url:
|
242
|
+
return self._create_url(s3_client, self.bucket_name, object_name), False
|
243
|
+
return object_name, False
|
244
|
+
|
212
245
|
if format_file not in ["png", "jpeg", "svg", "html", "pdf"]:
|
213
246
|
raise Exception("Invalid format_file provided. Supported formats are: png, jpeg, svg, html, pdf")
|
214
247
|
if format_file == "png":
|
@@ -224,15 +257,13 @@ class S3Client:
|
|
224
257
|
else:
|
225
258
|
raise Exception("Invalid MIME type provided")
|
226
259
|
|
227
|
-
s3_resource = self._get_s3_resource()
|
228
|
-
|
229
260
|
s3_resource.Bucket(self.bucket_name).Object(object_name).put(Body=bytes_data, ContentType=mimetypes)
|
230
|
-
|
261
|
+
return self._create_url(s3_client, self.bucket_name, object_name), True
|
231
262
|
except Exception as e:
|
232
263
|
logger.error(f"Error uploading image: {str(e)}")
|
233
264
|
raise Exception(f"Error uploading image: {str(e)}")
|
234
265
|
|
235
|
-
def upload_image(self, *args, **kwargs: Any) -> str:
|
266
|
+
def upload_image(self, *args, **kwargs: Any) -> tuple[str, bool]:
|
236
267
|
"""
|
237
268
|
Upload a Plotly Figure as a PNG image to an S3 bucket and generate a pre-signed URL.
|
238
269
|
|
@@ -240,6 +271,11 @@ class S3Client:
|
|
240
271
|
fig (Figure): The Plotly Figure object to upload.
|
241
272
|
bucket_name (str): The name of the S3 bucket.
|
242
273
|
object_name (str): The name of the S3 object.
|
274
|
+
format_file (str): Format of the image. Defaults to 'png' ["png", "jpeg", "svg", "html"].
|
275
|
+
overwrite (bool): If True, overwrite the existing file in S3. Defaults to False.
|
276
|
+
presigned_url (bool): If True, generate a pre-signed URL for the uploaded image. Defaults to False.
|
277
|
+
Raises:
|
278
|
+
Exception: If there is an error uploading the image.
|
243
279
|
|
244
280
|
Keyword Args:
|
245
281
|
format_file (str): Format of the image. Defaults to 'png'.
|
@@ -258,6 +294,13 @@ class S3Client:
|
|
258
294
|
else:
|
259
295
|
fig = kwargs.get("fig", None)
|
260
296
|
object_name = kwargs.get("object_name", None)
|
297
|
+
|
298
|
+
overwrite = kwargs.get("overwrite", False)
|
299
|
+
presigned_url = kwargs.get("presigned_url", False)
|
300
|
+
|
301
|
+
# Get S3 client and resource
|
302
|
+
s3_client = self._get_s3_client()
|
303
|
+
s3_resource = self._get_s3_resource()
|
261
304
|
|
262
305
|
if fig is None:
|
263
306
|
raise Exception("Figure is None")
|
@@ -268,6 +311,12 @@ class S3Client:
|
|
268
311
|
format_file : FormatFile = kwargs.get("format_file", "svg")
|
269
312
|
mimetypes = "image/svg+xml"
|
270
313
|
|
314
|
+
if not overwrite and self.file_exists(object_name):
|
315
|
+
print(f"File {object_name} already exists in the bucket {self.bucket_name}. Use overwrite=True to overwrite it.")
|
316
|
+
if presigned_url:
|
317
|
+
return self._create_url(s3_client, self.bucket_name, object_name), False
|
318
|
+
return object_name, False
|
319
|
+
|
271
320
|
if format_file not in ["png", "jpeg", "svg", "html"]:
|
272
321
|
raise Exception("Invalid format_file provided. Supported formats are: png, jpeg, svg, html")
|
273
322
|
if format_file == "png":
|
@@ -281,10 +330,6 @@ class S3Client:
|
|
281
330
|
else:
|
282
331
|
raise Exception("Invalid MIME type provided")
|
283
332
|
|
284
|
-
# Get S3 client and resource
|
285
|
-
s3_client = self._get_s3_client()
|
286
|
-
s3_resource = self._get_s3_resource()
|
287
|
-
|
288
333
|
if format_file == "html":
|
289
334
|
# Convert the figure to SVG
|
290
335
|
file_text = self._html_from_figure(fig)
|
@@ -297,13 +342,13 @@ class S3Client:
|
|
297
342
|
s3_resource.Bucket(self.bucket_name).Object(object_name).put(Body=file_buffer, ContentType=mimetypes)
|
298
343
|
|
299
344
|
# Generate and return a pre-signed URL for the uploaded image
|
300
|
-
return self._create_url(s3_client, self.bucket_name, object_name)
|
345
|
+
return self._create_url(s3_client, self.bucket_name, object_name), True
|
301
346
|
|
302
347
|
except Exception as e:
|
303
348
|
logger.error(f"Error uploading image: {str(e)}")
|
304
349
|
raise Exception(f"Error uploading image: {str(e)}")
|
305
350
|
|
306
|
-
def upload_from_dataframe(self, *args : Any, **kwargs: Any) -> str:
|
351
|
+
def upload_from_dataframe(self, *args : Any, **kwargs: Any) -> tuple[str, bool]:
|
307
352
|
"""
|
308
353
|
Upload a DataFrame as an Excel file to an S3 bucket and generate a pre-signed URL.
|
309
354
|
|
@@ -312,6 +357,10 @@ class S3Client:
|
|
312
357
|
**kwargs (Any): Additional keyword arguments for AWS credentials, bucket name, and object name.
|
313
358
|
Keyword Args:
|
314
359
|
format_file (str): Format of the file. Defaults to 'xlsx'.
|
360
|
+
overwrite (bool): If True, overwrite the existing file in S3. Defaults to False.
|
361
|
+
presigned_url (bool): If True, generate a pre-signed URL for the uploaded file. Defaults to False.
|
362
|
+
Raises:
|
363
|
+
Exception: If there is an error uploading the file.
|
315
364
|
|
316
365
|
Returns:
|
317
366
|
str: Pre-signed URL for the uploaded file.
|
@@ -329,6 +378,9 @@ class S3Client:
|
|
329
378
|
# Get the DataFrame and object name from the keyword arguments
|
330
379
|
df = kwargs.get("df", None)
|
331
380
|
object_name = kwargs.get("object_name", None)
|
381
|
+
|
382
|
+
overwrite = kwargs.get("overwrite", False)
|
383
|
+
presigned_url = kwargs.get("presigned_url", False)
|
332
384
|
|
333
385
|
if df is None:
|
334
386
|
raise Exception("Figure is None")
|
@@ -350,8 +402,15 @@ class S3Client:
|
|
350
402
|
else:
|
351
403
|
raise Exception("Invalid MIME type provided")
|
352
404
|
|
405
|
+
# Get S3 client and resource
|
353
406
|
s3_client = self._get_s3_client()
|
354
407
|
s3_resource = self._get_s3_resource()
|
408
|
+
|
409
|
+
if not overwrite and self.file_exists(object_name):
|
410
|
+
print(f"File {object_name} already exists in the bucket {self.bucket_name}. Use overwrite=True to overwrite it.")
|
411
|
+
if presigned_url:
|
412
|
+
return self._create_url(s3_client, self.bucket_name, object_name), False
|
413
|
+
return object_name, False
|
355
414
|
|
356
415
|
# Create a file buffer
|
357
416
|
ext: str = ""
|
@@ -382,7 +441,7 @@ class S3Client:
|
|
382
441
|
|
383
442
|
logger.info(f"Uploaded file to S3: {object_name}")
|
384
443
|
|
385
|
-
return self._create_url(s3_client, self.bucket_name, object_name)
|
444
|
+
return self._create_url(s3_client, self.bucket_name, object_name), True
|
386
445
|
except Exception as e:
|
387
446
|
logger.error(f"Error uploading file: {str(e)}")
|
388
447
|
raise Exception(f"Error uploading file: {str(e)}")
|
@@ -413,15 +472,19 @@ class S3Client:
|
|
413
472
|
logger.error(f"Error deleting files: {str(e)}")
|
414
473
|
raise Exception(f"Error deleting files: {str(e)}")
|
415
474
|
|
416
|
-
def upload_to_pdf(self, *args: Any, **kwargs: Any) -> str:
|
475
|
+
def upload_to_pdf(self, *args: Any, **kwargs: Any) -> tuple[str, bool]:
|
417
476
|
"""
|
418
477
|
Export the given text as a PDF and upload it to the S3 bucket.
|
419
478
|
|
420
479
|
Args:
|
421
480
|
text (str): The text to write in the PDF.
|
422
481
|
object_name (str): The name of the S3 object.
|
482
|
+
presigned_url (bool): If True, generate a pre-signed URL for the uploaded PDF. Defaults to False.
|
483
|
+
overwrite (bool): If True, overwrite the existing file in S3. Defaults to False
|
484
|
+
|
423
485
|
Raises:
|
424
486
|
Exception: If there is an error exporting the PDF.
|
487
|
+
|
425
488
|
Returns:
|
426
489
|
str: Pre-signed URL for the uploaded PDF.
|
427
490
|
"""
|
@@ -432,6 +495,9 @@ class S3Client:
|
|
432
495
|
else:
|
433
496
|
text = kwargs.get("text", None)
|
434
497
|
object_name = kwargs.get("object_name", None)
|
498
|
+
|
499
|
+
overwrite = kwargs.get("overwrite", False)
|
500
|
+
presigned_url = kwargs.get("presigned_url", False)
|
435
501
|
|
436
502
|
if text is None:
|
437
503
|
raise Exception("Text is None")
|
@@ -440,8 +506,15 @@ class S3Client:
|
|
440
506
|
raise Exception("Object name is None")
|
441
507
|
|
442
508
|
mimetypes = "application/pdf"
|
509
|
+
# Get S3 client and resource
|
443
510
|
s3_client = self._get_s3_client()
|
444
511
|
s3_resource = self._get_s3_resource()
|
512
|
+
|
513
|
+
if not overwrite and self.file_exists(object_name):
|
514
|
+
print(f"File {object_name} already exists in the bucket {self.bucket_name}. Use overwrite=True to overwrite it.")
|
515
|
+
if presigned_url:
|
516
|
+
return self._create_url(s3_client, self.bucket_name, object_name), False
|
517
|
+
return object_name, False
|
445
518
|
|
446
519
|
# Crea il PDF in memoria
|
447
520
|
pdf_buffer = BytesIO()
|
@@ -450,29 +523,47 @@ class S3Client:
|
|
450
523
|
c.setFont("Helvetica", 10)
|
451
524
|
x_margin = 20 * mm
|
452
525
|
y = height - 20 * mm
|
526
|
+
max_width = width - 2 * x_margin
|
527
|
+
|
528
|
+
def split_line(line, font_name, font_size):
|
529
|
+
# Divide la riga in più righe se supera la larghezza massima
|
530
|
+
words = line.split()
|
531
|
+
lines = []
|
532
|
+
current = ""
|
533
|
+
for word in words:
|
534
|
+
test = current + (" " if current else "") + word
|
535
|
+
if c.stringWidth(test, font_name, font_size) <= max_width:
|
536
|
+
current = test
|
537
|
+
else:
|
538
|
+
if current:
|
539
|
+
lines.append(current)
|
540
|
+
current = word
|
541
|
+
if current:
|
542
|
+
lines.append(current)
|
543
|
+
return lines
|
453
544
|
|
454
545
|
for line in text.strip().split('\n'):
|
455
546
|
line = line.strip()
|
456
|
-
if y < 20 * mm:
|
457
|
-
c.showPage()
|
458
|
-
c.setFont("Helvetica", 10)
|
459
|
-
y = height - 20 * mm
|
460
|
-
|
461
547
|
# Markdown-style header detection
|
462
548
|
if line.startswith("### "):
|
463
|
-
|
549
|
+
font_name, font_size = "Helvetica-Bold", 11
|
464
550
|
line = line[4:]
|
465
551
|
elif line.startswith("## "):
|
466
|
-
|
552
|
+
font_name, font_size = "Helvetica-Bold", 12
|
467
553
|
line = line[3:]
|
468
554
|
elif line.startswith("# "):
|
469
|
-
|
555
|
+
font_name, font_size = "Helvetica-Bold", 14
|
470
556
|
line = line[2:]
|
471
557
|
else:
|
472
|
-
|
558
|
+
font_name, font_size = "Helvetica", 10
|
473
559
|
|
474
|
-
|
475
|
-
|
560
|
+
for subline in split_line(line, font_name, font_size):
|
561
|
+
if y < 20 * mm + font_size:
|
562
|
+
c.showPage()
|
563
|
+
y = height - 20 * mm
|
564
|
+
c.setFont(font_name, font_size)
|
565
|
+
c.drawString(x_margin, y, subline)
|
566
|
+
y -= font_size + 2 # Spazio tra le righe
|
476
567
|
|
477
568
|
c.save()
|
478
569
|
pdf_buffer.seek(0)
|
@@ -482,7 +573,7 @@ class S3Client:
|
|
482
573
|
Body=pdf_buffer,
|
483
574
|
ContentType=mimetypes
|
484
575
|
)
|
485
|
-
return self._create_url(s3_client, self.bucket_name, object_name)
|
576
|
+
return self._create_url(s3_client, self.bucket_name, object_name), True
|
486
577
|
|
487
578
|
except Exception as e:
|
488
579
|
logger.error(f"Error exporting PDF: {str(e)}")
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|