"""Lambda function module.""" from owsrequest import request from sentry_sdk import capture_exception from src import audio_validation_logic from src import config from src import lambda_exceptions from src import s3 from src import status from src.constants import errors from src.constants import general from src.lambda_exceptions import LoggedException from src.metadata_validator import InvalidAudioError def create_transcoding_by_preset( bucket, key, preset_alias, metadata, status_topic_alias=None): """Call ows-transcoding create transcoding by preset. Args: bucket (str): Bucket where file is stored. key (str): Target S3 key. preset_alias (str): Alias for transcoding creation. metadata (dict): Extracted metadata status_topic_alias (str): Alias for sns topic. Returns: bool: True if success else raise Exception. """ try: request_url = config.POST_TRANSCODING_BY_PRESET_PATH.format( preset_alias=preset_alias) # internal => external formatting metadata_mapping = { 'channels': 'channels', 'codec': 'codec', 'container': 'container', 'sample_rate': 'sample_rate', 'bits_per_sample': 'bit_depth', 'bit_rate': 'bit_rate' } data = { 'input': { 'bucket': bucket, 'key': key, 'metadata': { v: metadata.get(k) for k, v in metadata_mapping.items() } }, 'status_topic_alias': status_topic_alias } response = request.process( application=config.APPLICATION_NAME, environment=config.ENVIRONMENT, method='POST', service_name=config.OWS_TRANSCODING_SERVICE_NAME, path=request_url, json=data ) if response.status_code != 200: error_text = ( errors.POST_TRANSCODING_BY_PRESET_ERROR_MESSAGE.format( status=response.status_code, text=response.text)) raise Exception(error_text) return True except Exception as e: config.logger.exception(str(e)) raise def _get_notify_params(bucket, key, exception): return { 'function': general.LAMBDA_NAME, 'error_status': general.AUDIO_VALIDATION_ERROR_STATUS, 'error_code': errors.AUDIO_VALIDATION_ERROR_CODE, 'bucket': bucket, 'filename': key, 'error_params': { 'message': str(exception) }, 'input_params': { 'key': key, 'bucket': bucket }, } def handler(event, context): """Lambda entry point. Args: event (dict): Information about uploaded audio. context (dict): Environment state. Returns: dict: Dict with validation result. """ bucket = event['bucket'] key = event['key'] asset_upload_type = event['asset_upload_type'] if asset_upload_type != general.ASSET_UPLOAD_STEREO: lambda_exceptions.notify_and_raise( general.LAMBDA_NAME, general.AUDIO_VALIDATION_ERROR_STATUS, errors.AUDIO_WRONG_ASSET_UPLOAD_TYPE_ERROR_CODE, key, bucket, { 'key': key, 'bucket': bucket, 'type': asset_upload_type}) if not s3.object_exists(bucket, key): lambda_exceptions.notify_and_raise( general.LAMBDA_NAME, general.AUDIO_VALIDATION_ERROR_STATUS, errors.S3_FILE_NOT_FOUND_CODE, key, bucket, { 'key': key, 'bucket': bucket}) try: metadata = audio_validation_logic.validate_audio_asset(bucket, key) create_transcoding_by_preset( bucket=bucket, key=key, preset_alias='{}_mezzanine'.format(config.ENVIRONMENT), metadata=metadata, status_topic_alias=general.SNS_STATUS_TOPIC_ALIAS) status.send_general_status( general.LAMBDA_NAME, general.AUDIO_VALIDATION_COMPLETE_STATUS, key, bucket=bucket) return {'is_valid': True} except InvalidAudioError as invalid_audio_error: lambda_exceptions.notify( **_get_notify_params(bucket, key, invalid_audio_error) ) return {'is_valid': False} except LoggedException: raise except Exception as exception: capture_exception(exception) # raise LoggedException which will result in the sfn retrying lambda_exceptions.notify_and_raise( **_get_notify_params(bucket, key, exception) )