KeyError:s3 PUT事件触发了AWS Lambda中的“记录”

时间:2019-11-29 06:44:48

标签: amazon-web-services amazon-s3 aws-lambda

我试图创建一个简单的事件驱动的AWS Lambda Python函数,以从另一服务(例如Amazon SES)存储在S3中的电子邮件中提取ZIP或GZIP附件。

from __future__ import print_function

import email
import zipfile
import os
import gzip
import string
import boto3
import urllib

print('Loading function')

s3 = boto3.client('s3')
s3r = boto3.resource('s3')
xmlDir = "/tmp/output/"

outputBucket = ""  # Set here for a seperate bucket otherwise it is set to the events bucket
outputPrefix = "xml/"  # Should end with /


def lambda_handler(event, context):
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key']).decode('utf8')

    try:
        # Set outputBucket if required
        if not outputBucket:
            global outputBucket
            outputBucket = bucket

        # Use waiter to ensure the file is persisted
        waiter = s3.get_waiter('object_exists')
        waiter.wait(Bucket=bucket, Key=key)

        response = s3r.Bucket(bucket).Object(key)

        # Read the raw text file into a Email Object
        msg = email.message_from_string(response.get()["Body"].read())

        if len(msg.get_payload()) == 2:

            # Create directory for XML files (makes debugging easier)
            if os.path.isdir(xmlDir) == False:
                os.mkdir(xmlDir)

            # The first attachment
            attachment = msg.get_payload()[1]

            # Extract the attachment into /tmp/output
            extract_attachment(attachment)

            # Upload the XML files to S3
            upload_resulting_files_to_s3()

        else:
            print("Could not see file/attachment.")

        return 0
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist '
            'and your bucket is in the same region as this '
            'function.'.format(key, bucket))
        raise e


def extract_attachment(attachment):
    # Process filename.zip attachments
    if "gzip" in attachment.get_content_type():
        contentdisp = string.split(attachment.get('Content-Disposition'), '=')
        fname = contentdisp[1].replace('\"', '')
        open('/tmp/' + contentdisp[1], 'wb').write(attachment.get_payload(decode=True))
        # This assumes we have filename.xml.gz, if we get this wrong, we will just
        # ignore the report
        xmlname = fname[:-3]
        open(xmlDir + xmlname, 'wb').write(gzip.open('/tmp/' + contentdisp[1], 'rb').read())

    # Process filename.xml.gz attachments (Providers not complying to standards)
    elif "zip" in attachment.get_content_type():
        open('/tmp/attachment.zip', 'wb').write(attachment.get_payload(decode=True))
        with zipfile.ZipFile('/tmp/attachment.zip', "r") as z:
            z.extractall(xmlDir)

    else:
        print('Skipping ' + attachment.get_content_type())


def upload_resulting_files_to_s3():
    # Put all XML back into S3 (Covers non-compliant cases if a ZIP contains multiple results)
    for fileName in os.listdir(xmlDir):
        if fileName.endswith(".xml"):
            print("Uploading: " + fileName)  # File name to upload
            s3r.meta.client.upload_file(xmlDir+'/'+fileName, outputBucket, outputPrefix+fileName)

在运行我遇到此错误的功能时

'Records': KeyError
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 25, in lambda_handler
    for record in event["Records"]:
KeyError: 'Records'

我尝试使用Google搜索,发现很少有人告诉我添加映射模板-https://intellipaat.com/community/18329/keyerror-records-in-aws-s3-lambda-trigger,     "KeyError: 'Records'" in AWS S3 - Lambda trigger,     跟随此链接,但出现其他错误

'query': KeyError 
Traceback (most recent call last): 
File "/var/task/lambda_function.py", line 24, in lambda_handler 
for record in event['query']['Records']: 
KeyError: 'query'

0 个答案:

没有答案