# python/02-object-storage.py"""Object storage integration patterns and cloud storage strategies"""fromtypingimportList,Dict,Any,Optional,Union,Tupleimportboto3frombotocore.exceptionsimportClientErrorimportgoogle.cloud.storageasgcsfromazure.storage.blobimportBlobServiceClientimportosimportjsonfromdatetimeimportdatetime,timedeltaimportloggingfromdataclassesimportdataclassfromenumimportEnumimportasyncioimportaiohttpfromconcurrent.futuresimportThreadPoolExecutorlogger=logging.getLogger(__name__)classStorageProvider(Enum):"""Storage provider enumeration"""AWS_S3="aws_s3"GOOGLE_GCS="google_gcs"AZURE_BLOB="azure_blob"MINIO="minio"@dataclassclassObjectMetadata:"""Object metadata definition"""key:strsize:intcontent_type:strlast_modified:datetimeetag:strmetadata:Dict[str,str]defto_dict(self)->Dict[str,Any]:"""Convert to dictionary"""return{"key":self.key,"size":self.size,"content_type":self.content_type,"last_modified":self.last_modified.isoformat(),"etag":self.etag,"metadata":self.metadata}classS3StorageManager:"""AWS S3 storage manager"""def__init__(self,bucket_name:str,region:str="us-east-1"):self.bucket_name=bucket_nameself.region=regionself.s3_client=boto3.client('s3',region_name=region)self.s3_resource=boto3.resource('s3',region_name=region)self.bucket=self.s3_resource.Bucket(bucket_name)defupload_object(self,key:str,data:bytes,content_type:str="application/octet-stream",metadata:Optional[Dict[str,str]]=None)->bool:"""Upload object to S3"""try:extra_args={'ContentType':content_type}ifmetadata:extra_args['Metadata']=metadataself.s3_client.put_object(Bucket=self.bucket_name,Key=key,Body=data,**extra_args)logger.info(f"Object uploaded to S3: {key}")returnTrueexceptClientErrorase:logger.error(f"Failed to upload object to S3: {e}")returnFalsedefdownload_object(self,key:str)->Optional[bytes]:"""Download object from S3"""try:response=self.s3_client.get_object(Bucket=self.bucket_name,Key=key)returnresponse['Body'].read()exceptClientErrorase:logger.error(f"Failed to download object from S3: {e}")returnNonedefdelete_object(self,key:str)->bool:"""Delete object from S3"""try:self.s3_client.delete_object(Bucket=self.bucket_name,Key=key)logger.info(f"Object deleted from S3: {key}")returnTrueexceptClientErrorase:logger.error(f"Failed to delete object from S3: {e}")returnFalsedeflist_objects(self,prefix:str="",max_keys:int=1000)->List[ObjectMetadata]:"""List objects in S3 bucket"""try:response=self.s3_client.list_objects_v2(Bucket=self.bucket_name,Prefix=prefix,MaxKeys=max_keys)objects=[]forobjinresponse.get('Contents',[]):metadata=ObjectMetadata(key=obj['Key'],size=obj['Size'],content_type=obj.get('ContentType','application/octet-stream'),last_modified=obj['LastModified'],etag=obj['ETag'],metadata=obj.get('Metadata',{}))objects.append(metadata)returnobjectsexceptClientErrorase:logger.error(f"Failed to list objects in S3: {e}")return[]defgenerate_presigned_url(self,key:str,expiration:int=3600)->Optional[str]:"""Generate presigned URL for object"""try:url=self.s3_client.generate_presigned_url('get_object',Params={'Bucket':self.bucket_name,'Key':key},ExpiresIn=expiration)returnurlexceptClientErrorase:logger.error(f"Failed to generate presigned URL: {e}")returnNoneclassGCSStorageManager:"""Google Cloud Storage manager"""def__init__(self,bucket_name:str,project_id:str):self.bucket_name=bucket_nameself.project_id=project_idself.client=gcs.Client(project=project_id)self.bucket=self.client.bucket(bucket_name)defupload_object(self,key:str,data:bytes,content_type:str="application/octet-stream",metadata:Optional[Dict[str,str]]=None)->bool:"""Upload object to GCS"""try:blob=self.bucket.blob(key)blob.content_type=content_typeifmetadata:blob.metadata=metadatablob.upload_from_string(data)logger.info(f"Object uploaded to GCS: {key}")returnTrueexceptExceptionase:logger.error(f"Failed to upload object to GCS: {e}")returnFalsedefdownload_object(self,key:str)->Optional[bytes]:"""Download object from GCS"""try:blob=self.bucket.blob(key)returnblob.download_as_bytes()exceptExceptionase:logger.error(f"Failed to download object from GCS: {e}")returnNonedefdelete_object(self,key:str)->bool:"""Delete object from GCS"""try:blob=self.bucket.blob(key)blob.delete()logger.info(f"Object deleted from GCS: {key}")returnTrueexceptExceptionase:logger.error(f"Failed to delete object from GCS: {e}")returnFalsedeflist_objects(self,prefix:str="",max_results:int=1000)->List[ObjectMetadata]:"""List objects in GCS bucket"""try:blobs=self.bucket.list_blobs(prefix=prefix,max_results=max_results)objects=[]forblobinblobs:metadata=ObjectMetadata(key=blob.name,size=blob.size,content_type=blob.content_typeor'application/octet-stream',last_modified=blob.updated,etag=blob.etag,metadata=blob.metadataor{})objects.append(metadata)returnobjectsexceptExceptionase:logger.error(f"Failed to list objects in GCS: {e}")return[]defgenerate_signed_url(self,key:str,expiration:int=3600)->Optional[str]:"""Generate signed URL for object"""try:blob=self.bucket.blob(key)url=blob.generate_signed_url(version="v4",expiration=timedelta(seconds=expiration),method="GET")returnurlexceptExceptionase:logger.error(f"Failed to generate signed URL: {e}")returnNoneclassAzureBlobStorageManager:"""Azure Blob Storage manager"""def__init__(self,account_name:str,account_key:str,container_name:str):self.account_name=account_nameself.account_key=account_keyself.container_name=container_nameself.blob_service_client=BlobServiceClient(account_url=f"https://{account_name}.blob.core.windows.net",credential=account_key)self.container_client=self.blob_service_client.get_container_client(container_name)defupload_object(self,key:str,data:bytes,content_type:str="application/octet-stream",metadata:Optional[Dict[str,str]]=None)->bool:"""Upload object to Azure Blob Storage"""try:blob_client=self.container_client.get_blob_client(key)upload_options={'content_type':content_type}ifmetadata:upload_options['metadata']=metadatablob_client.upload_blob(data,**upload_options)logger.info(f"Object uploaded to Azure Blob: {key}")returnTrueexceptExceptionase:logger.error(f"Failed to upload object to Azure Blob: {e}")returnFalsedefdownload_object(self,key:str)->Optional[bytes]:"""Download object from Azure Blob Storage"""try:blob_client=self.container_client.get_blob_client(key)returnblob_client.download_blob().readall()exceptExceptionase:logger.error(f"Failed to download object from Azure Blob: {e}")returnNonedefdelete_object(self,key:str)->bool:"""Delete object from Azure Blob Storage"""try:blob_client=self.container_client.get_blob_client(key)blob_client.delete_blob()logger.info(f"Object deleted from Azure Blob: {key}")returnTrueexceptExceptionase:logger.error(f"Failed to delete object from Azure Blob: {e}")returnFalsedeflist_objects(self,prefix:str="",max_results:int=1000)->List[ObjectMetadata]:"""List objects in Azure Blob container"""try:blobs=self.container_client.list_blobs(name_starts_with=prefix)objects=[]count=0forblobinblobs:ifcount>=max_results:breakmetadata=ObjectMetadata(key=blob.name,size=blob.size,content_type=blob.content_settings.content_typeor'application/octet-stream',last_modified=blob.last_modified,etag=blob.etag,metadata=blob.metadataor{})objects.append(metadata)count+=1returnobjectsexceptExceptionase:logger.error(f"Failed to list objects in Azure Blob: {e}")return[]classMultiCloudStorageManager:"""Multi-cloud storage manager"""def__init__(self,providers:Dict[StorageProvider,Any]):self.providers=providersself.primary_provider=list(providers.keys())[0]self.replication_providers=list(providers.keys())[1:]defupload_object(self,key:str,data:bytes,content_type:str="application/octet-stream",metadata:Optional[Dict[str,str]]=None,replicate:bool=True)->bool:"""Upload object to primary provider and optionally replicate"""try:# Upload to primary providerprimary_success=self._upload_to_provider(self.primary_provider,key,data,content_type,metadata)ifnotprimary_success:returnFalse# Replicate to other providersifreplicate:self._replicate_object(key,data,content_type,metadata)returnTrueexceptExceptionase:logger.error(f"Failed to upload object: {e}")returnFalsedefdownload_object(self,key:str,provider:Optional[StorageProvider]=None)->Optional[bytes]:"""Download object from specified provider or try all providers"""ifprovider:returnself._download_from_provider(provider,key)# Try primary provider firstdata=self._download_from_provider(self.primary_provider,key)ifdata:returndata# Try other providersforproviderinself.replication_providers:data=self._download_from_provider(provider,key)ifdata:returndatareturnNonedefdelete_object(self,key:str)->bool:"""Delete object from all providers"""success=Trueforproviderinself.providers.keys():ifnotself._delete_from_provider(provider,key):success=Falsereturnsuccessdef_upload_to_provider(self,provider:StorageProvider,key:str,data:bytes,content_type:str,metadata:Optional[Dict[str,str]])->bool:"""Upload object to specific provider"""try:ifprovider==StorageProvider.AWS_S3:returnself.providers[provider].upload_object(key,data,content_type,metadata)elifprovider==StorageProvider.GOOGLE_GCS:returnself.providers[provider].upload_object(key,data,content_type,metadata)elifprovider==StorageProvider.AZURE_BLOB:returnself.providers[provider].upload_object(key,data,content_type,metadata)returnFalseexceptExceptionase:logger.error(f"Failed to upload to {provider}: {e}")returnFalsedef_download_from_provider(self,provider:StorageProvider,key:str)->Optional[bytes]:"""Download object from specific provider"""try:ifprovider==StorageProvider.AWS_S3:returnself.providers[provider].download_object(key)elifprovider==StorageProvider.GOOGLE_GCS:returnself.providers[provider].download_object(key)elifprovider==StorageProvider.AZURE_BLOB:returnself.providers[provider].download_object(key)returnNoneexceptExceptionase:logger.error(f"Failed to download from {provider}: {e}")returnNonedef_delete_from_provider(self,provider:StorageProvider,key:str)->bool:"""Delete object from specific provider"""try:ifprovider==StorageProvider.AWS_S3:returnself.providers[provider].delete_object(key)elifprovider==StorageProvider.GOOGLE_GCS:returnself.providers[provider].delete_object(key)elifprovider==StorageProvider.AZURE_BLOB:returnself.providers[provider].delete_object(key)returnFalseexceptExceptionase:logger.error(f"Failed to delete from {provider}: {e}")returnFalsedef_replicate_object(self,key:str,data:bytes,content_type:str,metadata:Optional[Dict[str,str]])->None:"""Replicate object to other providers"""defreplicate_to_provider(provider:StorageProvider):try:self._upload_to_provider(provider,key,data,content_type,metadata)exceptExceptionase:logger.error(f"Failed to replicate to {provider}: {e}")# Replicate in parallelwithThreadPoolExecutor(max_workers=len(self.replication_providers))asexecutor:futures=[executor.submit(replicate_to_provider,provider)forproviderinself.replication_providers]forfutureinfutures:try:future.result()exceptExceptionase:logger.error(f"Replication error: {e}")# Usage examplesdefexample_object_storage():"""Example object storage usage"""# S3 storages3_manager=S3StorageManager("my-bucket","us-east-1")# Upload objectupload_success=s3_manager.upload_object("test.txt",b"Hello, S3!","text/plain")print(f"S3 upload success: {upload_success}")# Download objectdata=s3_manager.download_object("test.txt")print(f"S3 download result: {data}")# List objectsobjects=s3_manager.list_objects()print(f"S3 objects: {len(objects)}")# Generate presigned URLurl=s3_manager.generate_presigned_url("test.txt")print(f"S3 presigned URL: {url}")# GCS storagegcs_manager=GCSStorageManager("my-bucket","my-project")# Upload objectgcs_success=gcs_manager.upload_object("test.txt",b"Hello, GCS!","text/plain")print(f"GCS upload success: {gcs_success}")# Multi-cloud storageproviders={StorageProvider.AWS_S3:s3_manager,StorageProvider.GOOGLE_GCS:gcs_manager}multi_cloud_manager=MultiCloudStorageManager(providers)# Upload with replicationmulti_success=multi_cloud_manager.upload_object("multi.txt",b"Hello, Multi-Cloud!","text/plain")print(f"Multi-cloud upload success: {multi_success}")# Download from any providermulti_data=multi_cloud_manager.download_object("multi.txt")print(f"Multi-cloud download result: {multi_data}")