I m trying to send video metadata to MongoDB Atlas from an s3 bucket with media info as an AWS Lambda in Python 3.7. It works when I hardcode the data, but I receive either an object key error or an attribute error. I tried importing json and using json.loads() and json.dumps() and receive errors. Here's the code,
import boto3
from botocore.client import Config
from botocore.exceptions import ClientError
import json
import xmltodict
import subprocess
import os
import uuid
import requests
import json
# Generate a presigned URL for S3 Object
def get_presigned_url(expiration, objBucket, objKey):
s3 = boto3.client('s3', 'us-east-1', config=Config(s3={'addressing_style': 'virtual'}))
Params={
'Bucket': objBucket,
'Key': objKey
}
print ('CORE:: Media Evaluator:: Bucket Name: ' + objBucket)
print ('CORE:: Media Evaluator:: Object Key: ' + objKey)
try:
response = s3.generate_presigned_url('get_object', Params, ExpiresIn=expiration)
print('this is the response !!!!!!!!!', response)
except ClientError as e:
print (e)
raise
return None
return response
# Get MD5 from S3 Object Tag
def get_md5_from_objectTag(objBucket, objKey):
s3 = boto3.client('s3', 'us-east-1', config=Config(s3={'addressing_style': 'virtual'}))
response = s3.get_object_tagging(
Bucket=objBucket,
Key=objKey
)
for tag in response['TagSet']:
if tag['Key'] == 'MD5':
md5 = tag['Value']
return md5
# Evaluate the media using MediaInfo
def get_mediainfo(presignedURL):
print("presignedURL !!!!!!!!!!!!!", presignedURL)
try:
output = subprocess.check_output(['./mediainfo', '--full', '--output=JSON', presignedURL], shell=False, stderr=subprocess.STDOUT)
# subprocess.check_output(["./mediainfo", "--full", "--output=JSON", presignedURL], stdin=None, stderr=subprocess.STDOUT, shell=True)
print("this si the output !!!!!!!!!!!!!!!!!", output)
json_output = json.loads(output)
print("this is the JOSN output!!!!!!", json_output)
# Prepare the short media analysis JSON
json_track = json_output['media']
for f in json_track['track']:
if f['@type'] == 'General':
wrapper = f['Format']
if f['@type'] == 'Video':
wrapperType = f['Format_Profile']
codec = f['Format']
bitRate = f['BitRate']
#frameRate = f['FrameRate']
#som = f['TimeCode_FirstFrame']
width = f['Width']
height = f['Height']
#framecount = f['FrameCount']
#if f['@type'] == 'Other' and f['Type'] == 'Time code':
#som = f['TimeCode_FirstFrame']
mediaResult = {
"Wrapper": wrapper + wrapperType,
"Codec": codec,
"BitRate": bitRate,
#"FrameRate": frameRate,
#"SOM": som,
"Resolution": width + 'X' + height,
#"FrameCount": framecount
}
except Exception as e:
print (e)
raise
return None
return mediaResult
def lambda_handler(event, context):
print("this is the event !!!!!!!!!!!!!!!", event)
bucketName = event['bucketName']
objectName = event['objectKey']
signed_url = get_presigned_url(3600, bucketName, objectName)
print ('CORE:: Media Evaluator:: Presigned URL: ' + signed_url)
mediaAnalysis = get_mediainfo(signed_url)
print('CORE:: Media Evaluator:: Parsed Media Analysis: ' + json.dumps(mediaAnalysis, indent=4))
#md5 = get_md5_from_objectTag(bucketName, objectName)
#print('CORE:: Media Evaluator:: MD5 Value from Object Tag: ' + md5)
ingestData = {
"MediaEvaluation": mediaAnalysis,
#"MD5": md5,
"AssetID": objectName.partition(".")[0],
"AssetUID": uuid.uuid4().hex,
"Bucket": bucketName,
"ObjectKey": objectName
}
print('this is ingestData !!!!!!!!!!!!!!!!!!!!!!!', ingestData)
print('this is mediaAnalysis !!!!!!!!!!!!!!!!!!!!!!!', mediaAnalysis)
#ingestDataJson = json.dumps(ingestData)
#mediaAnalysisJson = json.dumps(mediaAnalysis)
dataNotFake = { 's3url': ingestData.Bucket + '.s3.amazonaws.com/' + ingestData.objectKey,
'Codec': mediaAnalysis.Codec, 'resolution': mediaAnalysis.Resolution}
r = requests.post(url ='<mongobdAtlasUrlConnectStringHere>', data = dataNotFake)
return ingestData
what I am sending the Lambda is,
{
"bucketName": "<s3-bucket-name>",
"objectKey": "<video-file-name>"
}
edit: the initial response
{
"errorMessage": "'str' object has no attribute 'Bucket'",
"errorType": "AttributeError",
"stackTrace": [
" File \"/var/task/mediaEvaluator.py\", line 107, in lambda_handler\n dataNotFake = { 's3url': ingestDataJson.Bucket + '.s3.amazonaws.com/' + ingestDataJson.objectKey, 'Codec': mediaAnalysisJson.Codec, 'resolution': mediaAnalysisJson.Resolution}\n"
]
}
and, then the logs
7c4Uwzk422qMqIJfcFOZr6kwDasq3AEIy%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FARAAGgw2MTYwODIzMjAyOTEiDHJGza1WClZUa%2BZKEyqwAWPyeYiNirreNeRtXlelQjCxUnEj3HMZiMF2UlPLpzwY3RRNo5LBpieIuIRUm7HtbWqXp19lDsUBHiGSoZqmNW5i5EN5nTPe6c6LNdKYFXYutvd4X1dsVEij8srY0DW%2FjBpiZxGt3DlhLWiDtoA8EjgXEe4JcpvU6Z9EpJeotjFhBzfe%2BM7xoPYE%2BoYS4ipx0nyntPQ4Qia1Cdh9LBwsHbcPL59JeI27lVmkggCFevZXMLqPzIEGOuABHPLi%2B3fu1bxwoDJYaA0HOwnAbF%2FncPMWpIR9NATDHyq%2B6BbaOxFAygyNXC%2FAjjqCEOezv1yfZ0VCMAP9i0Wi%2BBqgL8s4Qbuwk1PdgSfZdwqxrSOynSeX6s7Z5au9QYn%2BY%2F5upVr%2F5dt6Q8veRAWuqEQx4muzEix0jorBm4j1KAmuTYfv3A71Hv9YfhMmbR6h4XZv1U8nQpqNJNIJ%2FC%2BBBbRuXDWMhbfnK6IiXw9e3VWqQa7Esjj0WqHgOZ1wWGLZvqqy5Re%2Bm%2BF9eFdE%2F3mUv516aeU31eZ0gkHxnZGZ6HY%3D&Expires=1613960653', 'track': [{'@type': 'General', 'ID': '1', 'VideoCount': '1', 'MenuCount': '1', 'FileExtension': 'mpg?AWSAccessKeyId=ASIAY64K6FOR54JVBB5W&Signature=b16%2BkSWWYrrZvBlYA5tvs7DsqO4%3D&x-amz-security-token=IQoJb3JpZ2luX2VjEML%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJHMEUCIQCyP7t3a9Y6%2F4brzVhIOH5GEMpkargZlHCnX55tbiJKwQIgdBNqAwljhCiLZbf%2F7c4Uwzk422qMqIJfcFOZr6kwDasq3AEIy%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FARAAGgw2MTYwODIzMjAyOTEiDHJGza1WClZUa%2BZKEyqwAWPyeYiNirreNeRtXlelQjCxUnEj3HMZiMF2UlPLpzwY3RRNo5LBpieIuIRUm7HtbWqXp19lDsUBHiGSoZqmNW5i5EN5nTPe6c6LNdKYFXYutvd4X1dsVEij8srY0DW%2FjBpiZxGt3DlhLWiDtoA8EjgXEe4JcpvU6Z9EpJeotjFhBzfe%2BM7xoPYE%2BoYS4ipx0nyntPQ4Qia1Cdh9LBwsHbcPL59JeI27lVmkggCFevZXMLqPzIEGOuABHPLi%2B3fu1bxwoDJYaA0HOwnAbF%2FncPMWpIR9NATDHyq%2B6BbaOxFAygyNXC%2FAjjqCEOezv1yfZ0VCMAP9i0Wi%2BBqgL8s4Qbuwk1PdgSfZdwqxrSOynSeX6s7Z5au9QYn%2BY%2F5upVr%2F5dt6Q8veRAWuqEQx4muzEix0jorBm4j1KAmuTYfv3A71Hv9YfhMmbR6h4XZv1U8nQpqNJNIJ%2FC%2BBBbRuXDWMhbfnK6IiXw9e3VWqQa7Esjj0WqHgOZ1wWGLZvqqy5Re%2Bm%2BF9eFdE%2F3mUv516aeU31eZ0gkHxnZGZ6HY%3D&Expires=1613960653', 'Format': 'MPEG-TS', 'FileSize': '102004664', 'Duration': '200.236328125', 'OverallBitRate_Mode': 'CBR', 'OverallBitRate': '4075040', 'StreamSize': '7646822', 'extra': {'OverallBitRate_Precision_Min': '4075030', 'OverallBitRate_Precision_Max': '4075051', 'FileExtension_Invalid': 'ts m2t m2s m4t m4s tmf ts tp trp ty'}}, {'@type': 'Video', 'StreamOrder': '0-0', 'ID': '481', 'MenuID': '1', 'Format': 'AVC', 'Format_Profile': 'Main', 'Format_Level': '4.1', 'Format_Settings_CABAC': 'Yes', 'Format_Settings_RefFrames': '1', 'Format_Settings_GOP': 'M=1, N=15', 'CodecID': '27', 'Duration': '194.867', 'BitRate': '3873733', 'Width': '1280', 'Height': '720', 'Sampled_Width': '1280', 'Sampled_Height': '720', 'PixelAspectRatio': '1.000', 'DisplayAspectRatio': '1.778', 'ColorSpace': 'YUV', 'ChromaSubsampling': '4:2:0', 'BitDepth': '8', 'ScanType': 'Progressive', 'Delay': '10.000000', 'StreamSize': '94357842'}, {'@type': 'Menu', 'StreamOrder': '0', 'ID': '480', 'MenuID': '1', 'Format': 'AVC / KLV', 'Duration': '200.236328125', 'Delay': '0.001107222', 'List_StreamKind': '1 / ', 'List_StreamPos': '0 / ', 'extra': {'pointer_field': '0', 'section_length': '55'}}]}}
CORE:: Media Evaluator:: Parsed Media Analysis: {
"Wrapper": "MPEG-TSMain",
"Codec": "AVC",
"BitRate": "3873733",
"Resolution": "1280X720"
}
this is ingestData !!!!!!!!!!!!!!!!!!!!!!! {'MediaEvaluation': {'Wrapper': 'MPEG-TSMain', 'Codec': 'AVC', 'BitRate': '3873733', 'Resolution': '1280X720'}, 'AssetID': 'Day Flight', 'AssetUID': 'cb0651e1151f41a5a890425d41bda3cb', 'Bucket': 'video-uploads-94viwznlhm88', 'ObjectKey': 'Day Flight.mpg'}
this is mediaAnalysis !!!!!!!!!!!!!!!!!!!!!!! {'Wrapper': 'MPEG-TSMain', 'Codec': 'AVC', 'BitRate': '3873733', 'Resolution': '1280X720'}
[ERROR] AttributeError: 'str' object has no attribute 'Bucket'
Traceback (most recent call last):
File "/var/task/mediaEvaluator.py", line 107, in lambda_handler
dataNotFake = { 's3url': ingestDataJson.Bucket + '.s3.amazonaws.com/' + ingestDataJson.objectKey, 'Codec': mediaAnalysisJson.Codec, 'resolution': mediaAnalysisJson.Resolution}
END RequestId: bfcf3bb8-d709-44c5-9e42-8c7a6a31a879
REPORT RequestId: bfcf3bb8-d709-44c5-9e42-8c7a6a31a879 Duration: 6679.29 ms Billed Duration: 6680 ms Memory Size: 128 MB Max Memory Used: 104 MB Init Duration: 382.19 ms
I think here
dataNotFake = { 's3url': ingestData.Bucket + '.s3.amazonaws.com/' + ingestData.objectKey,
considering these
ingestData = {'MediaEvaluation': {'Wrapper': 'MPEG-TSMain',
'Codec': 'AVC',
'BitRate': '3873733',
'Resolution': '1280X720'},
'AssetID': 'Day Flight',
'AssetUID': 'cb0651e1151f41a5a890425d41bda3cb',
'Bucket': 'video-uploads-94viwznlhm88',
'ObjectKey': 'Day Flight.mpg'}
mediaAnalysis = {
'Wrapper': 'MPEG-TSMain', 'Codec': 'AVC', 'BitRate': '3873733', 'Resolution': '1280X720'}
You should use something like this
dataNotFake = {
's3url': f'{ingestData["Bucket"]}.s3.amazonaws.com/{ingestData["ObjectKey"]}',
'Codec': mediaAnalysis['Codec'],
'resolution': mediaAnalysis['Resolution']
}