internal.block.management
Block storage management module.
1"""Block storage management module.""" 2 3import asyncio 4from io import BytesIO 5 6from fastapi import HTTPException, UploadFile, status 7from minio import Minio, S3Error 8from PIL import Image 9 10from internal.settings.env import block_settings 11 12PROFILE_IMAGES_BUCKET = "profileimages" 13BUNDLE_IMAGES_BUCKET = "bundleimages" 14MAX_SIZE = 5 * 1024 * 1024 # 5mb 15 16 17async def process_image(file: UploadFile) -> bytes: 18 """Confirm image and compress. 19 20 Args: 21 file: uploaded file 22 23 Returns: 24 compressed image 25 26 Raises: 27 HTTPException: if not jpeg or larger then 5mb 28 """ 29 if file.content_type != "image/jpeg": 30 raise HTTPException( 31 status.HTTP_400_BAD_REQUEST, "only jpeg images are accepted" 32 ) 33 file_bytes = await file.read() 34 if len(file_bytes) > MAX_SIZE: 35 raise HTTPException(status_code=400, detail="image must be under 5mb") 36 image = Image.open(BytesIO(file_bytes)) 37 output = BytesIO() 38 image.save(output, format="JPEG", quality=85, optimize=True) 39 return output.getvalue() 40 41 42class BlockManagement: 43 """Block storage management class.""" 44 45 client: Minio 46 47 def initialise(self) -> None: 48 """Initialise block storage connection.""" 49 self.client = Minio( 50 endpoint=block_settings.url_port, 51 access_key=block_settings.access_key, 52 secret_key=block_settings.secret_key, 53 secure=False, 54 ) 55 if not self.client.bucket_exists(PROFILE_IMAGES_BUCKET): 56 self.client.make_bucket(PROFILE_IMAGES_BUCKET) 57 if not self.client.bucket_exists(BUNDLE_IMAGES_BUCKET): 58 self.client.make_bucket(BUNDLE_IMAGES_BUCKET) 59 60 async def upload_profile_image(self, user_id: int, file: UploadFile) -> None: 61 """Change user profile image. 62 63 Args: 64 user_id: user id 65 file: uploaded file 66 """ 67 image_bytes = await process_image(file) 68 await asyncio.to_thread( 69 self.client.put_object, 70 bucket_name=PROFILE_IMAGES_BUCKET, 71 object_name=f"{user_id}.jpeg", 72 data=BytesIO(image_bytes), 73 length=len(image_bytes), 74 content_type="image/jpeg", 75 ) 76 77 async def upload_bundle_image(self, bundle_id: int, file: UploadFile) -> None: 78 """Change bundle image. 79 80 Args: 81 bundle_id: bundle id 82 file: uploaded file 83 """ 84 image_bytes = await process_image(file) 85 await asyncio.to_thread( 86 self.client.put_object, 87 bucket_name=BUNDLE_IMAGES_BUCKET, 88 object_name=f"{bundle_id}.jpeg", 89 data=BytesIO(image_bytes), 90 length=len(image_bytes), 91 content_type="image/jpeg", 92 ) 93 94 def get_profile_image(self, user_id: int) -> bytes: 95 """Get user profile image. 96 97 Args: 98 user_id: user id 99 100 Returns: 101 image bytes 102 103 Raises: 104 HTTPException: if failed to get image 105 """ 106 try: 107 image = self.client.get_object(PROFILE_IMAGES_BUCKET, f"{user_id}.jpeg") 108 try: 109 return image.read() 110 finally: 111 image.close() 112 image.release_conn() 113 except S3Error as err: 114 if err.code == "NoSuchKey": 115 raise HTTPException(status.HTTP_404_NOT_FOUND, "image not found") 116 raise HTTPException( 117 status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to get image" 118 ) 119 120 def get_bundle_image(self, bundle_id: int) -> bytes: 121 """Get bundle image. 122 123 Args: 124 bundle_id: bundle id 125 126 Returns: 127 image bytes 128 129 Raises: 130 HTTPException: if failed to get image 131 """ 132 try: 133 image = self.client.get_object(BUNDLE_IMAGES_BUCKET, f"{bundle_id}.jpeg") 134 try: 135 return image.read() 136 finally: 137 image.close() 138 image.release_conn() 139 except S3Error as err: 140 if err.code == "NoSuchKey": 141 raise HTTPException(status.HTTP_404_NOT_FOUND, "image not found") 142 raise HTTPException( 143 status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to get image" 144 ) 145 146 147block_management = BlockManagement()
PROFILE_IMAGES_BUCKET =
'profileimages'
BUNDLE_IMAGES_BUCKET =
'bundleimages'
MAX_SIZE =
5242880
async def
process_image(file: fastapi.datastructures.UploadFile) -> bytes:
18async def process_image(file: UploadFile) -> bytes: 19 """Confirm image and compress. 20 21 Args: 22 file: uploaded file 23 24 Returns: 25 compressed image 26 27 Raises: 28 HTTPException: if not jpeg or larger then 5mb 29 """ 30 if file.content_type != "image/jpeg": 31 raise HTTPException( 32 status.HTTP_400_BAD_REQUEST, "only jpeg images are accepted" 33 ) 34 file_bytes = await file.read() 35 if len(file_bytes) > MAX_SIZE: 36 raise HTTPException(status_code=400, detail="image must be under 5mb") 37 image = Image.open(BytesIO(file_bytes)) 38 output = BytesIO() 39 image.save(output, format="JPEG", quality=85, optimize=True) 40 return output.getvalue()
Confirm image and compress.
Arguments:
- file: uploaded file
Returns:
compressed image
Raises:
- HTTPException: if not jpeg or larger then 5mb
class
BlockManagement:
43class BlockManagement: 44 """Block storage management class.""" 45 46 client: Minio 47 48 def initialise(self) -> None: 49 """Initialise block storage connection.""" 50 self.client = Minio( 51 endpoint=block_settings.url_port, 52 access_key=block_settings.access_key, 53 secret_key=block_settings.secret_key, 54 secure=False, 55 ) 56 if not self.client.bucket_exists(PROFILE_IMAGES_BUCKET): 57 self.client.make_bucket(PROFILE_IMAGES_BUCKET) 58 if not self.client.bucket_exists(BUNDLE_IMAGES_BUCKET): 59 self.client.make_bucket(BUNDLE_IMAGES_BUCKET) 60 61 async def upload_profile_image(self, user_id: int, file: UploadFile) -> None: 62 """Change user profile image. 63 64 Args: 65 user_id: user id 66 file: uploaded file 67 """ 68 image_bytes = await process_image(file) 69 await asyncio.to_thread( 70 self.client.put_object, 71 bucket_name=PROFILE_IMAGES_BUCKET, 72 object_name=f"{user_id}.jpeg", 73 data=BytesIO(image_bytes), 74 length=len(image_bytes), 75 content_type="image/jpeg", 76 ) 77 78 async def upload_bundle_image(self, bundle_id: int, file: UploadFile) -> None: 79 """Change bundle image. 80 81 Args: 82 bundle_id: bundle id 83 file: uploaded file 84 """ 85 image_bytes = await process_image(file) 86 await asyncio.to_thread( 87 self.client.put_object, 88 bucket_name=BUNDLE_IMAGES_BUCKET, 89 object_name=f"{bundle_id}.jpeg", 90 data=BytesIO(image_bytes), 91 length=len(image_bytes), 92 content_type="image/jpeg", 93 ) 94 95 def get_profile_image(self, user_id: int) -> bytes: 96 """Get user profile image. 97 98 Args: 99 user_id: user id 100 101 Returns: 102 image bytes 103 104 Raises: 105 HTTPException: if failed to get image 106 """ 107 try: 108 image = self.client.get_object(PROFILE_IMAGES_BUCKET, f"{user_id}.jpeg") 109 try: 110 return image.read() 111 finally: 112 image.close() 113 image.release_conn() 114 except S3Error as err: 115 if err.code == "NoSuchKey": 116 raise HTTPException(status.HTTP_404_NOT_FOUND, "image not found") 117 raise HTTPException( 118 status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to get image" 119 ) 120 121 def get_bundle_image(self, bundle_id: int) -> bytes: 122 """Get bundle image. 123 124 Args: 125 bundle_id: bundle id 126 127 Returns: 128 image bytes 129 130 Raises: 131 HTTPException: if failed to get image 132 """ 133 try: 134 image = self.client.get_object(BUNDLE_IMAGES_BUCKET, f"{bundle_id}.jpeg") 135 try: 136 return image.read() 137 finally: 138 image.close() 139 image.release_conn() 140 except S3Error as err: 141 if err.code == "NoSuchKey": 142 raise HTTPException(status.HTTP_404_NOT_FOUND, "image not found") 143 raise HTTPException( 144 status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to get image" 145 )
Block storage management class.
def
initialise(self) -> None:
48 def initialise(self) -> None: 49 """Initialise block storage connection.""" 50 self.client = Minio( 51 endpoint=block_settings.url_port, 52 access_key=block_settings.access_key, 53 secret_key=block_settings.secret_key, 54 secure=False, 55 ) 56 if not self.client.bucket_exists(PROFILE_IMAGES_BUCKET): 57 self.client.make_bucket(PROFILE_IMAGES_BUCKET) 58 if not self.client.bucket_exists(BUNDLE_IMAGES_BUCKET): 59 self.client.make_bucket(BUNDLE_IMAGES_BUCKET)
Initialise block storage connection.
async def
upload_profile_image(self, user_id: int, file: fastapi.datastructures.UploadFile) -> None:
61 async def upload_profile_image(self, user_id: int, file: UploadFile) -> None: 62 """Change user profile image. 63 64 Args: 65 user_id: user id 66 file: uploaded file 67 """ 68 image_bytes = await process_image(file) 69 await asyncio.to_thread( 70 self.client.put_object, 71 bucket_name=PROFILE_IMAGES_BUCKET, 72 object_name=f"{user_id}.jpeg", 73 data=BytesIO(image_bytes), 74 length=len(image_bytes), 75 content_type="image/jpeg", 76 )
Change user profile image.
Arguments:
- user_id: user id
- file: uploaded file
async def
upload_bundle_image(self, bundle_id: int, file: fastapi.datastructures.UploadFile) -> None:
78 async def upload_bundle_image(self, bundle_id: int, file: UploadFile) -> None: 79 """Change bundle image. 80 81 Args: 82 bundle_id: bundle id 83 file: uploaded file 84 """ 85 image_bytes = await process_image(file) 86 await asyncio.to_thread( 87 self.client.put_object, 88 bucket_name=BUNDLE_IMAGES_BUCKET, 89 object_name=f"{bundle_id}.jpeg", 90 data=BytesIO(image_bytes), 91 length=len(image_bytes), 92 content_type="image/jpeg", 93 )
Change bundle image.
Arguments:
- bundle_id: bundle id
- file: uploaded file
def
get_profile_image(self, user_id: int) -> bytes:
95 def get_profile_image(self, user_id: int) -> bytes: 96 """Get user profile image. 97 98 Args: 99 user_id: user id 100 101 Returns: 102 image bytes 103 104 Raises: 105 HTTPException: if failed to get image 106 """ 107 try: 108 image = self.client.get_object(PROFILE_IMAGES_BUCKET, f"{user_id}.jpeg") 109 try: 110 return image.read() 111 finally: 112 image.close() 113 image.release_conn() 114 except S3Error as err: 115 if err.code == "NoSuchKey": 116 raise HTTPException(status.HTTP_404_NOT_FOUND, "image not found") 117 raise HTTPException( 118 status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to get image" 119 )
Get user profile image.
Arguments:
- user_id: user id
Returns:
image bytes
Raises:
- HTTPException: if failed to get image
def
get_bundle_image(self, bundle_id: int) -> bytes:
121 def get_bundle_image(self, bundle_id: int) -> bytes: 122 """Get bundle image. 123 124 Args: 125 bundle_id: bundle id 126 127 Returns: 128 image bytes 129 130 Raises: 131 HTTPException: if failed to get image 132 """ 133 try: 134 image = self.client.get_object(BUNDLE_IMAGES_BUCKET, f"{bundle_id}.jpeg") 135 try: 136 return image.read() 137 finally: 138 image.close() 139 image.release_conn() 140 except S3Error as err: 141 if err.code == "NoSuchKey": 142 raise HTTPException(status.HTTP_404_NOT_FOUND, "image not found") 143 raise HTTPException( 144 status.HTTP_500_INTERNAL_SERVER_ERROR, "failed to get image" 145 )
Get bundle image.
Arguments:
- bundle_id: bundle id
Returns:
image bytes
Raises:
- HTTPException: if failed to get image
block_management =
<BlockManagement object>