"""S3 common functions.""" import boto3 import botocore from src.config import EXPECTED_BUCKET_OWNER from src.config import logger client = boto3.client('s3') resource = boto3.resource('s3') def put_object(bucket, key, data, **kwargs): """Put object to S3. Args: bucket (str): target S3 bucket. key (str): target S3 key. data (bytes): file data. kwargs (dict): extra arguments. """ return client.put_object(Bucket=bucket, Key=key, Body=data, **kwargs) def object_exists(bucket, key): """Check if S3 object exists. Args: bucket (str): target S3 bucket. key (str): target S3 key. """ try: client.head_object( Bucket=bucket, Key=key, ExpectedBucketOwner=EXPECTED_BUCKET_OWNER ) except botocore.exceptions.ClientError as e: if e.response['Error']['Code'] == '404': return False else: raise else: return True def head_object(bucket, key): """Retrieve object metadata without object downloading. Args: bucket (str): target S3 bucket. key (str): target object key. Returns: dict: Response from S3. """ return client.head_object( Bucket=bucket, Key=key, ExpectedBucketOwner=EXPECTED_BUCKET_OWNER ) def download_file_object(bucket, key, file_object, **kwargs): """Download s3 object to file-like buffer. Args: bucket (str): target S3 bucket. key (str): target S3 key. file_object (io.BytesIO): file data. kwargs (dict): extra arguments. """ return client.download_fileobj( Bucket=bucket, Key=key, Fileobj=file_object, ExtraArgs={'ExpectedBucketOwner': EXPECTED_BUCKET_OWNER}, **kwargs ) def upload_file_objects(file_descriptors, bucket, content_type='binary/octet'): """Upload file objects to s3. Args: file_descriptors (list): List of file descriptors. bucket (str): target S3 bucket. content_type (str): Content Type """ try: for descriptor in file_descriptors: descriptor['output_image_buffer'].seek(0) put_object( bucket=bucket, key=descriptor['key'], data=descriptor['output_image_buffer'], ContentType=content_type ) except Exception as e: logger.exception(str(e)) raise return True