"""Amazon S3 connector.""" import boto3 from botocore.exceptions import ClientError from oto import response from masters_registry import config from masters_registry.connectors import sentry from masters_registry.constant import error client = boto3.client('s3') def get_file_url(file_key, expires_in=86400): """Generate download url for provided file in s3 bucket. Args: file_key (str): path to file for which url should be generated. expires_in (int): lifetime of url. Default is 1 day. Returns: Response: Response with url in message or with errors. """ bucket_name = config.REPORTS_BUCKET_NAME if not check_if_file_exists(file_key): if sentry.sentry_client: sentry.sentry_client.captureException() message = error.S3_FILE_NOT_FOUND .format( key=file_key, bucket=bucket_name) return response.create_not_found_response(message) url = client.generate_presigned_url( 'get_object', Params={'Bucket': bucket_name, 'Key': file_key}, ExpiresIn=expires_in ) return response.Response(url) def upload_file_object(file_key, file_data): """Upload file obejct to S3 . Args: file_key (str): key of a file that should be uploaded to s3 bucket. file_data (StringIO): file content """ client.upload_fileobj( file_data, config.REPORTS_BUCKET_NAME, file_key) def check_if_file_exists(file_key): """Checks if file exists in s3 bucket. Args: file_key (str): path to a file Returns: bool: Whether file exists """ try: client.head_object( Bucket=config.REPORTS_BUCKET_NAME, Key=file_key) except ClientError as error: return int(error.response['Error']['Code']) != 404 return True