"""Module for s3_file model.""" from boto3.s3 import transfer from botocore.exceptions import ClientError from transcoding import config from transcoding.connectors import logger from transcoding.connectors import s3 def upload_s3_file(source_path, destination_bucket, destination_key): """Copy file from source_path to s3 bucket. Args: source_path (str): Source file path. destination_bucket (str): S3 bucket. destination_key (str): S3 bucket key. Returns: response.Response: Response with success or error message. Raises: ClientError: If ClientError happens during upload. Exception: In case of any other error during upload. """ s3_client = s3.get_s3_client() try: file_body = open(source_path, 'rb') upload_response = s3_client.put_object( Body=file_body, Bucket=destination_bucket, Key=destination_key) return upload_response except ClientError as e: error_code = e.response['Error']['Code'] error_message = 'S3 file upload failed with code {code}'.format( code=error_code) logger.app_logger.exception(error_message) raise except Exception as e: error_message = 'S3 file upload failed with error {error}'.format( error=(str(e))) logger.app_logger.exception(error_message) raise def copy_s3_file(source_bucket, source_key, destination_bucket, destination_key): """Copy file from source bucket to destination bucket. Args: source_bucket (str): Source S3 bucket. source_key (str): Source S3 bucket key. destination_bucket (str): Destination S3 bucket. destination_key (str): Destination S3 bucket key. """ s3_client = s3.get_s3_client() try: copy_source = { 'Bucket': source_bucket, 'Key': source_key } s3_client.copy( CopySource=copy_source, Bucket=destination_bucket, Key=destination_key, ExtraArgs={'TaggingDirective': 'REPLACE', 'Tagging': ''}, Config=transfer.TransferConfig( multipart_threshold=config.S3_UPLOAD_CHUNK_SIZE, multipart_chunksize=config.S3_UPLOAD_CHUNK_SIZE, ), ) except ClientError as e: error_code = e.response['Error']['Code'] error_message = 'S3 file copy failed with code {code}'.format( code=error_code) logger.app_logger.exception(error_message) raise except Exception as e: error_message = 'S3 file copy failed with error {error}'.format( error=(str(e))) logger.app_logger.exception(error_message) raise def create_presigned_url( bucket, key, client_method='get_object', expires_in=86400): """Generate a presigned url. Args: bucket (str): Bucket name. key (str): Existing S3 object key. client_method (str): Client method for operation by result URL. expires_in (int): The number of seconds the presigned url is valid for. By default it expires in 24 hours (86400 seconds). Returns: str: Presigned url. """ s3_client = s3.get_s3_client() try: presigned_url = s3_client.generate_presigned_url( ClientMethod=client_method, ExpiresIn=expires_in, Params={ 'Bucket': bucket, 'Key': key } ) return presigned_url except ClientError as e: error_code = e.response['Error']['Code'] error_message = ( 'S3 generating presigned url failed with code {code}'.format( code=error_code)) logger.app_logger.exception(error_message) raise # TODO raising of custom exception except Exception as e: error_message = 'S3 file upload failed with error {error}'.format( error=(str(e))) logger.app_logger.exception(error_message) raise # TODO raising of custom exception