Terarea  2
The automation project
Loading...
Searching...
No Matches
bucket.py
Go to the documentation of this file.
1"""_summary_
2 File in charge of providing a boiled down interface for interracting with an s3 bucket.
3"""
4
5from typing import List, Union, Dict, Any, Optional
6import boto3
7from botocore.client import Config
8from botocore.exceptions import BotoCoreError, ClientError
9from display_tty import Disp, TOML_CONF, FILE_DESCRIPTOR, SAVE_TO_FILE, FILE_NAME
10from ..components import CONST
11
12
13class Bucket:
14 """
15 Class to manage interaction with an S3-compatible bucket like MinIO.
16 """
17
18 def __init__(self, error: int = 84, success: int = 0, debug: bool = False) -> None:
19 self.debug: bool = debug
20 self.error: int = error
21 self.success: int = success
22
23 # ------------------------ The logging function ------------------------
24 self.disp: Disp = Disp(
25 TOML_CONF,
26 FILE_DESCRIPTOR,
27 SAVE_TO_FILE,
28 FILE_NAME,
29 debug=self.debug,
30 logger=self.__class__.__name__
31 )
32 # ----------------------- The connector address -----------------------
33 self.connection: Optional[boto3.resource] = None
34
35 def connect(self) -> int:
36 """
37 Connect to the S3 bucket or MinIO service.
38
39 Returns:
40 int: success or error code.
41 """
42 try:
43 self.connection = boto3.resource(
44 's3',
45 # MinIO URL
46 endpoint_url=f"{CONST.MINIO_HOST}:{CONST.MINIO_PORT}",
47 aws_access_key_id=CONST.MINIO_ROOT_USER, # MinIO root user
48 aws_secret_access_key=CONST.MINIO_ROOT_PASSWORD, # MinIO password
49 config=Config(signature_version='s3v4')
50 )
51 # Check connection by listing buckets
52 self.connection.meta.client.list_buckets()
53 self.disp.log_info("Connection to MinIO S3 successful.", "connect")
54 return self.success
55 except (BotoCoreError, ClientError) as e:
56 self.disp.log_error(
57 f"Failed to connect to MinIO: {str(e)}",
58 "connect"
59 )
60 return self.error
61
62 def is_connected(self) -> bool:
63 """
64 Check if the connection to the S3-compatible service is active.
65
66 Returns:
67 bool: True if connected, False otherwise.
68 """
69 if self.connection is None:
70 self.disp.log_error("No connection object found.", "is_connected")
71 return False
72
73 try:
74 # Attempt to list buckets as a simple test of the connection
75 self.connection.meta.client.list_buckets()
76 self.disp.log_info("Connection is active.", "is_connected")
77 return True
78 except (BotoCoreError, ClientError, ConnectionError) as e:
79 self.disp.log_error(
80 f"Connection check failed: {str(e)}",
81 "is_connected"
82 )
83 return False
84
85 def disconnect(self) -> int:
86 """
87 Disconnect from the S3-compatible service by setting the connection to None.
88
89 Returns:
90 int: success or error code.
91 """
92 if self.connection is None:
93 self.disp.log_warning(
94 "No active connection to disconnect.",
95 "disconnect"
96 )
97 return self.error
98
99 try:
100 self.connection = None
101 self.disp.log_info(
102 "Disconnected from the S3-compatible service.",
103 "disconnect"
104 )
105 return self.success
106 except Exception as e:
107 self.disp.log_error(
108 f"Failed to disconnect: {str(e)}",
109 "disconnect"
110 )
111 return self.error
112
113 def get_bucket_names(self) -> Union[List[str], int]:
114 """
115 Retrieve a list of all bucket names.
116
117 Returns:
118 Union[List[str], int]: A list of bucket names or error code.
119 """
120 try:
121 if self.connection is None:
122 raise ConnectionError("No connection established.")
123 buckets = [bucket.name for bucket in self.connection.buckets.all()]
124 return buckets
125 except (BotoCoreError, ClientError, ConnectionError) as e:
126 self.disp.log_error(
127 f"Error fetching bucket names: {str(e)}",
128 "get_bucket_names"
129 )
130 return self.error
131
132 def create_bucket(self, bucket_name: str) -> int:
133 """
134 Create a new bucket.
135
136 Args:
137 bucket_name (str): Name of the bucket to create.
138
139 Returns:
140 int: success or error code.
141 """
142 try:
143 if self.connection is None:
144 raise ConnectionError("No connection established.")
145 self.connection.create_bucket(Bucket=bucket_name)
146 self.disp.log_info(
147 f"Bucket '{bucket_name}' created successfully.",
148 "create_bucket"
149 )
150 return self.success
151 except (BotoCoreError, ClientError, ConnectionError) as e:
152 self.disp.log_error(
153 f"Failed to create bucket '{bucket_name}': {str(e)}",
154 "create_bucket"
155 )
156 return self.error
157
158 def upload_file(self, bucket_name: str, file_path: str, key_name: Optional[str] = None) -> int:
159 """
160 Upload a file to the specified bucket.
161
162 Args:
163 bucket_name (str): Name of the target bucket.
164 file_path (str): Path of the file to upload.
165 key_name (Optional[str]): Name to save the file as in the bucket. Defaults to the file path name.
166
167 Returns:
168 int: success or error code.
169 """
170 key_name = key_name or file_path
171 try:
172 if self.connection is None:
173 raise ConnectionError("No connection established.")
174 self.connection.Bucket(bucket_name).upload_file(
175 file_path, key_name)
176 msg = f"File '{file_path}' uploaded to bucket "
177 msg += f"'{bucket_name}' as '{key_name}'."
178 self.disp.log_info(msg, "upload_file")
179 return self.success
180 except (BotoCoreError, ClientError, ConnectionError) as e:
181 msg = f"Failed to upload file '{file_path}' to bucket "
182 msg += f"'{bucket_name}': {str(e)}"
183 self.disp.log_error(msg, "upload_file")
184 return self.error
185
186 def download_file(self, bucket_name: str, key_name: str, destination_path: str) -> int:
187 """
188 Download a file from the specified bucket.
189
190 Args:
191 bucket_name (str): Name of the target bucket.
192 key_name (str): Name of the file to download.
193 destination_path (str): Local path where the file will be saved.
194
195 Returns:
196 int: success or error code.
197 """
198 try:
199 if self.connection is None:
200 raise ConnectionError("No connection established.")
201 self.connection.Bucket(bucket_name).download_file(
202 key_name, destination_path)
203 msg = f"File '{key_name}' downloaded from bucket "
204 msg += f"'{bucket_name}' to '{destination_path}'."
205 self.disp.log_info(msg, "download_file")
206 return self.success
207 except (BotoCoreError, ClientError, ConnectionError) as e:
208 msg = f"Failed to download file '{key_name}'"
209 msg += f" from bucket '{bucket_name}': {str(e)}"
210 self.disp.log_error(msg, "download_file")
211 return self.error
212
213 def delete_file(self, bucket_name: str, key_name: str) -> int:
214 """
215 Delete a file from the specified bucket.
216
217 Args:
218 bucket_name (str): Name of the bucket.
219 key_name (str): Name of the file to delete.
220
221 Returns:
222 int: success or error code.
223 """
224 try:
225 if self.connection is None:
226 raise ConnectionError("No connection established.")
227 self.connection.Bucket(bucket_name).Object(key_name).delete()
228 self.disp.log_info(
229 f"File '{key_name}' deleted from bucket '{bucket_name}'.",
230 "delete_file"
231 )
232 return self.success
233 except (BotoCoreError, ClientError, ConnectionError) as e:
234 msg = f"Failed to delete file '{key_name}' from bucket "
235 msg += f"'{bucket_name}': {str(e)}"
236 self.disp.log_error(msg, "delete_file")
237 return self.error
238
239 def delete_bucket(self, bucket_name: str) -> int:
240 """
241 Delete a bucket.
242
243 Args:
244 bucket_name (str): Name of the bucket to delete.
245
246 Returns:
247 int: success or error code.
248 """
249 try:
250 if self.connection is None:
251 raise ConnectionError("No connection established.")
252 self.connection.Bucket(bucket_name).delete()
253 self.disp.log_info(
254 f"Bucket '{bucket_name}' deleted successfully.",
255 "delete_bucket"
256 )
257 return self.success
258 except (BotoCoreError, ClientError, ConnectionError) as e:
259 self.disp.log_error(
260 f"Failed to delete bucket '{bucket_name}': {str(e)}",
261 "delete_bucket"
262 )
263 return self.error
264
265 def get_bucket_files(self, bucket_name: str) -> Union[List[str], int]:
266 """
267 List all files in the specified bucket.
268
269 Args:
270 bucket_name (str): Name of the bucket.
271
272 Returns:
273 Union[List[str], int]: List of file names or error code.
274 """
275 try:
276 if self.connection is None:
277 raise ConnectionError("No connection established.")
278 files = []
279 for obj in self.connection.Bucket(bucket_name).objects.all():
280 files.append(obj.key)
281 return files
282 except (BotoCoreError, ClientError, ConnectionError) as e:
283 msg = f"Failed to retrieve files from bucket '{bucket_name}'"
284 msg += f": {str(e)}"
285 self.disp.log_error(msg, "get_bucket_files")
286 return self.error
287
288 def get_bucket_file(self, bucket_name: str, key_name: str) -> Union[Dict[str, Any], int]:
289 """
290 Get information about a specific file in the bucket.
291
292 Args:
293 bucket_name (str): Name of the bucket.
294 key_name (str): Name of the file.
295
296 Returns:
297 Union[Dict[str, Any], int]: File metadata (path and size) or error code.
298 """
299 try:
300 if self.connection is None:
301 raise ConnectionError("No connection established.")
302 obj = self.connection.Bucket(bucket_name).Object(key_name)
303 return {'file_path': key_name, 'file_size': obj.content_length}
304 except (BotoCoreError, ClientError, ConnectionError) as e:
305 msg = f"Failed to get file '{key_name}'"
306 msg += f"from bucket '{bucket_name}': {str(e)}"
307 self.disp.log_error(msg, "get_bucket_file")
308 return self.error
Optional[boto3.resource] connection
Definition bucket.py:33
Union[List[str], int] get_bucket_names(self)
Definition bucket.py:113
int delete_file(self, str bucket_name, str key_name)
Definition bucket.py:213
int upload_file(self, str bucket_name, str file_path, Optional[str] key_name=None)
Definition bucket.py:158
None __init__(self, int error=84, int success=0, bool debug=False)
Definition bucket.py:18
Union[List[str], int] get_bucket_files(self, str bucket_name)
Definition bucket.py:265
Union[Dict[str, Any], int] get_bucket_file(self, str bucket_name, str key_name)
Definition bucket.py:288
int create_bucket(self, str bucket_name)
Definition bucket.py:132
int delete_bucket(self, str bucket_name)
Definition bucket.py:239
int download_file(self, str bucket_name, str key_name, str destination_path)
Definition bucket.py:186