"""Interface for managing sound recording versions in s3.""" import os import boto3 from botocore.exceptions import ClientError s3_client = boto3.client('s3') ENV_CONFIG = { 'dev': { 'bucket': 'test-orcd-bucket', 'prefix': 'sound_recording_versions/' }, 'qa': { 'bucket': 'qa-sr-versions-bucket', 'prefix': '' }, 'prod': { 'bucket': 'prod-sr-versions-bucket', 'prefix': '' } } def write_sound_recording_version(sound_recording_id, data): """Upload sound recording data. Args: sound_recording_id (str): unique id for sound recording data (str): json data to be saved Returns: str: latest s3 version unique ID str: new S3 version unique ID bool: if new version was created datetime: last modified date """ (bucket, prefix) = _config() latest_version_id = None new_version_id = None data = data.encode('UTF-8') ( latest_version_id, latest_version_data, last_modified ) = get_latest_sound_recording_version(sound_recording_id) updated = False if latest_version_data != data: put_response = s3_client.put_object( Bucket=bucket, Key=f'{prefix}{sound_recording_id}', Body=data ) new_version_id = put_response['VersionId'] updated = True return (latest_version_id, new_version_id, updated, last_modified) def get_sound_recording_version(sound_recording_id, version_id): """Retrieve sound recording data by version. Args: sound_recording_id (str): unique id version id (str): snapshot unique id Returns: str: data if retrieved else None """ (bucket, prefix) = _config() data = None last_modified = None try: response = s3_client.get_object( Bucket=bucket, Key=f'{prefix}{sound_recording_id}', VersionId=version_id ) data = response['Body'].read() last_modified = response['LastModified'] except ClientError as e: if e.response['Error']['Code'] == 'NoSuchKey' \ or e.response['Error']['Message'] == \ 'Invalid version id specified': return (data, last_modified) else: raise e return (data, last_modified) def get_latest_sound_recording_version(sound_recording_id): """Retrieve sound recording data. Args: sound_recording_id (str): unique id for sound recording Returns: str: latest s3 version unique ID else None str: data if retrieved else None datetime: last modified date else None """ (bucket, prefix) = _config() data = None version_id = None last_modified = None try: response = s3_client.get_object( Bucket=bucket, Key=f'{prefix}{sound_recording_id}' ) data = response['Body'].read() version_id = response['VersionId'] last_modified = response['LastModified'] except ClientError as e: if e.response['Error']['Code'] == 'NoSuchKey' \ or e.response['Error']['Message'] == \ 'Invalid version id specified': return ( version_id, data, last_modified) else: raise e return (version_id, data, last_modified) def _config(): """Get config based on value of Environment var.""" env = os.environ['ENVIRONMENT'] config = ENV_CONFIG[env] return ( config['bucket'], config['prefix'] )