# ================================================================================== # Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. # Permission is hereby granted, free of charge, to any person obtaining a copy of this # software and associated documentation files (the "Software"), to deal in the Software # without restriction, including without limitation the rights to use, copy, modify, # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # ================================================================================== # # stvblogTranscribeMedia # by: Rob Dachowski # For questions or feedback, please contact robdac@amazon.com # # Purpose: The labmda creates an AWS Translate job, updates the result path and returns. It is part of a step function process # # Change Log: # 3/1/2021: Initial version # # ================================================================================== import json import uuid import datetime import boto3 from botocore.exceptions import ClientError import ssmparms as sp import stmparms as stm import stverrors # ================================================================================== # Function: labmda_handler # Purpose: This is the "main" code for this lambda function # Parameters: # event - the JSON input structure containing the parameters from the step function process # ================================================================================== def lambda_handler(event, context): #debugging message print("===> stvblogTranslateTranscript: " + "\nEvent:" + str(event) ) print( "\t---> Boto Version: ", boto3.__version__ ) # Load the parms from DynamoDB parms = stm.get_stm_parms( event['input']['Outputs']['process']['ProcessName']) if not parms: # We have an issue, so get out raise stvDynamoDBError( "*** Unable to load parms from DynamoDB ***") # set up a shortcut pc = parms['Item']['Config'] pi = parms['Item']['Inputs'] po = parms['Item']['Outputs'] ptgts = parms['Item']['Targets'] pt = event['item']['translate'] sls = pi['sourceLanguageShort'] slf = pi['sourceLanguageFull'] tls = event['item']['translate']['targetLanguageShort'] tlf = event['item']['translate']['targetLanguageFull'] # set up AWS API variables s3 = boto3.resource( 's3') t = boto3.client( 'translate') # set up keys txJobName = 'translate_' + sls + '-' + tls + '_' + po['process']['uuid'] inputBucket = "s3://" + pc['baseBucketName'] + '/' + po['process']['uuid'] + '/' + pc['translationInput'] + '/' outputBucket = "s3://" + pc['baseBucketName'] + '/' + po['process']['uuid'] + '/' + pc['translationOutput'] + '/' + tls + '/' response = event tOut = {} tOut = event['item']['translate'] if tOut['translate'] == 'y': # We have been asked to translate this, so call Translate print( "\t---> Submitting ", sls, " to ", tls, " Translation Job for file: ") print( "\t\t--> Input: ", inputBucket) print( "\t\t--> Output: ", outputBucket) try: print( "\t---> Calling Translate.. ") r = t.start_text_translation_job( JobName=txJobName, InputDataConfig = { "S3Uri": inputBucket, 'ContentType': 'text/plain' }, OutputDataConfig = { "S3Uri": outputBucket }, DataAccessRoleArn=pc['translateDataAccessRoleARN'], SourceLanguageCode=sls, TargetLanguageCodes = [ tls ] ) print("\t---> Translation Job Submitted: " + str(t.describe_text_translation_job(JobId=r['JobId'])) ) # set up the translateJobOutput path in the JSON file. The path is defined in the Step Function status = t.describe_text_translation_job(JobId=r['JobId']) tOut['translateJobName'] = status['TextTranslationJobProperties']['JobName'] tOut['translateJobId'] = status['TextTranslationJobProperties']['JobId'] tOut['translateJobStatus'] = status['TextTranslationJobProperties']['JobStatus'] tOut['translateStartTimeStamp'] = status['TextTranslationJobProperties']['SubmittedTime'].strftime("%Y-%m-%d %H-%M-%S") except ClientError as e: print("*** Error submitting Transcription Job for ", sls, " to ", tls, " ***") raise stvError("*** Error Code: " + e.response['Error']['Message'] + " ***") else: if sls == tls: # The source and the target are the same, so no need for translation, just simply copy the input file to the output directory try: source = {"Bucket": pc['baseBucketName'], "Key": po['transcribe']['translatableTextKey'] } destination = s3.Bucket( pc['baseBucketName'] ) destinationKey = po['process']['uuid'] + '/' + pc['translationOutput'] + '/' + tls + '/' + 'translateableText-' + tls + '_' + po['process']['uuid'] + ".txt" print( "\t---> Translation Unncessary. Copying ", str(source), " to ", str(destination) + "/" + destinationKey) destination.copy( source, destinationKey) tOut['translateJobName'] = "N/A" tOut['translateJobId'] = "N/A" tOut['translateJobStatus'] = "COMPLETED" except ClientError as e: print("*** Error copying file " + " ***") raise stvError("*** Error Code: ", e.response['Error']['Message'] + " ***") else: tOut['translateJobName'] = "N/A" tOut['translateJobId'] = "N/A" tOut['translateJobStatus'] = "COMPLETED" # set up the response and the DynamoDB update info response['item']['translate'] = tOut ptgts[ event['index'] ]['translate'] = tOut # Put the ouptut back into DynamoDB if stm.update_stm_target( event['input']['Outputs']['process']['ProcessName'], ptgts[event['index']], event['index'] ): print('===> stvblogTranslateTranscript Complete') return response else: raise stvError( "*** Error writing to the stvblog table ***" )