sharedkernel 2.2.6__tar.gz → 2.3.0__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.
Files changed (39) hide show
  1. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/PKG-INFO +5 -1
  2. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/README.md +4 -0
  3. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/setup.py +1 -1
  4. sharedkernel-2.3.0/sharedkernel/multipart_upload.py +69 -0
  5. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/s3_uploader.py +50 -26
  6. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel.egg-info/PKG-INFO +5 -1
  7. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel.egg-info/SOURCES.txt +1 -0
  8. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/setup.cfg +0 -0
  9. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/common.py +0 -0
  10. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/data_format_converter.py +0 -0
  11. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/database/__init__.py +0 -0
  12. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/database/audit_model.py +0 -0
  13. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/database/mongo_generic_audit_repository.py +0 -0
  14. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/database/mongo_generic_repository.py +0 -0
  15. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/database/pagination_response_dto.py +0 -0
  16. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/date_converter.py +0 -0
  17. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/diff_utils.py +0 -0
  18. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/enum/__init__.py +0 -0
  19. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/enum/error_code.py +0 -0
  20. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/enum/sort_order.py +0 -0
  21. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/exception/__init__.py +0 -0
  22. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/exception/exception.py +0 -0
  23. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/exception/exception_handlers.py +0 -0
  24. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/jwt_service.py +0 -0
  25. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/normalizer/__init__.py +0 -0
  26. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/normalizer/number_normalizer.py +0 -0
  27. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/normalizer/phone_number_normalizer.py +0 -0
  28. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/normalizer/string_normalizer.py +0 -0
  29. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/objects/__init__.py +0 -0
  30. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/objects/base_document.py +0 -0
  31. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/objects/json_string_model.py +0 -0
  32. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/objects/jwt_model.py +0 -0
  33. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/objects/result.py +0 -0
  34. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/objects/user_info.py +0 -0
  35. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/regex_masking.py +0 -0
  36. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel/string_extentions.py +0 -0
  37. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel.egg-info/dependency_links.txt +0 -0
  38. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel.egg-info/requires.txt +0 -0
  39. {sharedkernel-2.2.6 → sharedkernel-2.3.0}/sharedkernel.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sharedkernel
3
- Version: 2.2.6
3
+ Version: 2.3.0
4
4
  Summary: sharekernel is a shared package between all python projects
5
5
  Author: Smilinno
6
6
  Description-Content-Type: text/markdown
@@ -29,6 +29,10 @@ Dynamic: summary
29
29
  this is a shared kernel package
30
30
 
31
31
  # Change Log
32
+ ### Version 2.3.0
33
+ - Implement multipart uploader for S3
34
+ ### Version 2.2.7
35
+ - add presigned url in s3 uploader
32
36
  ### Version 2.2.6
33
37
  - implement api key
34
38
  ### Version 2.2.5
@@ -2,6 +2,10 @@
2
2
  this is a shared kernel package
3
3
 
4
4
  # Change Log
5
+ ### Version 2.3.0
6
+ - Implement multipart uploader for S3
7
+ ### Version 2.2.7
8
+ - add presigned url in s3 uploader
5
9
  ### Version 2.2.6
6
10
  - implement api key
7
11
  ### Version 2.2.5
@@ -37,7 +37,7 @@ setup(
37
37
  "deepdiff",
38
38
  ],
39
39
  # *strongly* suggested for sharing
40
- version="2.2.6",
40
+ version="2.3.0",
41
41
  description="sharekernel is a shared package between all python projects",
42
42
  long_description=long_description,
43
43
  long_description_content_type="text/markdown",
@@ -0,0 +1,69 @@
1
+ class MultipartUploadSession:
2
+ MIN_PART_SIZE = 5 * 1024 * 1024 # 5MB
3
+
4
+ def __init__(self, s3_client, bucket, object_key, acl="private"):
5
+ self.s3 = s3_client
6
+ self.bucket = bucket
7
+ self.key = object_key
8
+ self.acl = acl
9
+
10
+ self.upload_id = None
11
+ self.parts = []
12
+ self.part_number = 1
13
+ self.buffer = bytearray()
14
+
15
+ self._start()
16
+
17
+ def _start(self):
18
+ resp = self.s3.create_multipart_upload(
19
+ Bucket=self.bucket,
20
+ Key=self.key,
21
+ ACL=self.acl,
22
+ )
23
+ self.upload_id = resp["UploadId"]
24
+
25
+ def upload_chunk(self, chunk: bytes):
26
+ """
27
+ Receives small chunks (KB) and buffers them
28
+ """
29
+ self.buffer.extend(chunk)
30
+
31
+ if len(self.buffer) >= self.MIN_PART_SIZE:
32
+ self._upload_part(bytes(self.buffer))
33
+ self.buffer.clear()
34
+
35
+ def _upload_part(self, data: bytes):
36
+ resp = self.s3.upload_part(
37
+ Bucket=self.bucket,
38
+ Key=self.key,
39
+ UploadId=self.upload_id,
40
+ PartNumber=self.part_number,
41
+ Body=data,
42
+ )
43
+
44
+ self.parts.append({
45
+ "ETag": resp["ETag"],
46
+ "PartNumber": self.part_number
47
+ })
48
+ self.part_number += 1
49
+
50
+ def complete(self):
51
+ # upload remaining buffer (can be < 5MB)
52
+ if self.buffer:
53
+ self._upload_part(bytes(self.buffer))
54
+ self.buffer.clear()
55
+
56
+ self.s3.complete_multipart_upload(
57
+ Bucket=self.bucket,
58
+ Key=self.key,
59
+ UploadId=self.upload_id,
60
+ MultipartUpload={"Parts": self.parts},
61
+ )
62
+
63
+ def abort(self):
64
+ if self.upload_id:
65
+ self.s3.abort_multipart_upload(
66
+ Bucket=self.bucket,
67
+ Key=self.key,
68
+ UploadId=self.upload_id,
69
+ )
@@ -1,62 +1,64 @@
1
+
1
2
  import requests
2
3
  import boto3
3
4
  from io import BytesIO
4
5
  import uuid
5
6
  import os
7
+ from sharedkernel.multipart_upload import MultipartUploadSession
6
8
 
7
9
  class S3Uploader:
8
10
  def __init__(self, endpoint_url, bucket, access_key, secret_key):
9
- """
10
- Initializes the S3Uploader with credentials and optional endpoint/region.
11
-
12
- :param endpoint_url: Custom endpoint URL (for S3-compatible services like MinIO)
13
- :param bucket: Name of S3 bucket
14
- :param access_key: Access key
15
- :param secret_key: Secret key
16
- """
17
11
  self.endpoint_url = endpoint_url
18
12
  self.bucket = bucket
19
13
  self.access_key = access_key
20
14
  self.secret_key = secret_key
21
15
 
22
- # Initialize the S3 client
23
16
  self.s3 = boto3.client(
24
17
  's3',
25
18
  endpoint_url=self.endpoint_url,
26
19
  aws_access_key_id=self.access_key,
27
20
  aws_secret_access_key=self.secret_key,
28
21
  )
29
-
30
- def upload_file_object(self, file_obj, object_name=None, file_extension=None, folder_name=None):
31
- """
32
- Uploads a file object to an S3 bucket and returns its URL.
33
-
34
- :param file_obj: File object to upload
35
- :param object_name: S3 file name to save as (optional)
36
- :param file_extension: File extension to append to object name (optional)
37
- :param folder_name: Optional folder name to save the file in
38
- :return: URL of the uploaded file if successful, else False
39
- """
40
- # Use uuid4 to generate a unique object_name if not provided
22
+
23
+ @staticmethod
24
+ def __generate_object_name(object_name=None, file_extension=None, folder_name=None):
41
25
  if object_name is None:
42
26
  object_name = str(uuid.uuid4())
43
27
 
44
- # Append the file extension to the object_name
45
28
  if file_extension:
46
29
  object_name += file_extension
47
30
 
48
- # Prefix the object name with the folder if provided
49
31
  if folder_name:
50
32
  object_name = f"{folder_name}/{object_name}"
33
+
34
+ return object_name
35
+
51
36
 
52
- # Upload the file object
53
- self.s3.upload_fileobj(file_obj, self.bucket, object_name, ExtraArgs={'ACL':'public-read'})
37
+ def upload_file_object(self, file_obj, object_name=None, file_extension=None, folder_name=None, public_read=True):
38
+ object_name = self.__generate_object_name(object_name, file_extension, folder_name)
39
+
40
+ acl = "public-read" if public_read else "private"
41
+
42
+ self.s3.upload_fileobj(file_obj, self.bucket, object_name, ExtraArgs={'ACL': acl})
54
43
 
55
- # Construct the URL of the uploaded file
56
44
  file_url = f"{self.endpoint_url}/{self.bucket}/{object_name}"
57
45
 
58
46
  return file_url
59
47
 
48
+ def generate_presigned_url(self, object_name=None, file_extension=None, folder_name=None, expire_time: int = 3600):
49
+ object_name = self.__generate_object_name(object_name, file_extension, folder_name)
50
+
51
+ temp_url = self.s3.generate_presigned_url(
52
+ 'get_object',
53
+ Params={
54
+ 'Bucket': self.bucket,
55
+ 'Key': object_name
56
+ },
57
+ ExpiresIn=expire_time
58
+ )
59
+
60
+ return temp_url
61
+
60
62
  def upload_file_from_url(self, file_url, object_name=None, folder_name=None):
61
63
  """
62
64
  Downloads a file from a URL and uploads it to an S3 bucket, returning its URL.
@@ -80,3 +82,25 @@ class S3Uploader:
80
82
  # Step 2: Upload the file to S3
81
83
  file_obj = BytesIO(response.content)
82
84
  return self.upload_file_object(file_obj=file_obj, object_name=object_name, file_extension=file_extension, folder_name=folder_name)
85
+
86
+ def create_multipart_session(
87
+ self,
88
+ object_name=None,
89
+ file_extension=None,
90
+ folder_name=None,
91
+ public_read=True,
92
+ ):
93
+ object_key = self.__generate_object_name(
94
+ object_name, file_extension, folder_name
95
+ )
96
+
97
+ acl = "public-read" if public_read else "private"
98
+
99
+ return MultipartUploadSession(
100
+ s3_client=self.s3,
101
+ bucket=self.bucket,
102
+ object_key=object_key,
103
+ acl=acl,
104
+ )
105
+
106
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sharedkernel
3
- Version: 2.2.6
3
+ Version: 2.3.0
4
4
  Summary: sharekernel is a shared package between all python projects
5
5
  Author: Smilinno
6
6
  Description-Content-Type: text/markdown
@@ -29,6 +29,10 @@ Dynamic: summary
29
29
  this is a shared kernel package
30
30
 
31
31
  # Change Log
32
+ ### Version 2.3.0
33
+ - Implement multipart uploader for S3
34
+ ### Version 2.2.7
35
+ - add presigned url in s3 uploader
32
36
  ### Version 2.2.6
33
37
  - implement api key
34
38
  ### Version 2.2.5
@@ -5,6 +5,7 @@ sharedkernel/data_format_converter.py
5
5
  sharedkernel/date_converter.py
6
6
  sharedkernel/diff_utils.py
7
7
  sharedkernel/jwt_service.py
8
+ sharedkernel/multipart_upload.py
8
9
  sharedkernel/regex_masking.py
9
10
  sharedkernel/s3_uploader.py
10
11
  sharedkernel/string_extentions.py
File without changes