Хороший вопрос, я перенес инициализацию клиента s3 за пределы лямбда-обработчика

то я хочу сделать:

Пользователь загружает CSV-файл в корзину AWS S3.После загрузки файла S3 Bucket вызывает лямбда-функцию, которую я создал.Моя лямбда-функция читает содержимое файла csv, а затем отправляет электронное письмо с содержанием файла

Местная среда

Безсерверный фреймворк версия 1.22.0

Python 2.7

Вот мой файл serverless.yml

service: aws-python # NOTE: update this with your service name

provider:
  name: aws
  runtime: python2.7
  stage: dev
  region: us-east-1
  iamRoleStatements:
        - Effect: "Allow"
          Action:
              - s3:*
              - "ses:SendEmail"
              - "ses:SendRawEmail"
              - "s3:PutBucketNotification"
          Resource: "*"

functions:
  csvfile:
    handler: handler.csvfile
    description: send mail whenever a csv file is uploaded on S3 
    events:
      - s3:
          bucket: mine2
          event: s3:ObjectCreated:*
          rules:
            - suffix: .csv

и вот моя лямбда-функция:

import json
import boto3
import botocore
import logging
import sys
import traceback
import csv

from botocore.exceptions import ClientError
from pprint import pprint
from time import strftime, gmtime
from json import dumps, loads, JSONEncoder, JSONDecoder


#setup simple logging for INFO
logger = logging.getLogger()
logger.setLevel(logging.INFO)

from botocore.exceptions import ClientError

def csvfile(event, context):
    """Send email whenever a csvfile is uploaded to S3 """
    body = {}
    emailcontent = ''
    status_code = 200
    #set email information
    email_from = '****@*****.com'
    email_to = '****@****.com'
    email_subject = 'new file is uploaded'
    try:
        s3 = boto3.resource(u's3')
        s3 = boto3.client('s3')
        for record in event['Records']:
            filename = record['s3']['object']['key']
            filesize = record['s3']['object']['size']
            source = record['requestParameters']['sourceIPAddress']
            eventTime = record['eventTime']
        # get a handle on the bucket that holds your file
        bucket = s3.Bucket(u'mine2')
        # get a handle on the object you want (i.e. your file)
        obj = bucket.Object(key= event[u'Records'][0][u's3'][u'object'][u'key'])
        # get the object
        response = obj.get()
        # read the contents of the file and split it into a list of lines
        lines = response[u'Body'].read().split()
        # now iterate over those lines
        for row in csv.DictReader(lines):    
            print(row)
            emailcontent = emailcontent + '\n' + row 
    except Exception as e:
        print(traceback.format_exc())
        status_code = 500
        body["message"] = json.dumps(e)

    email_body = "File Name: " + filename + "\n" + "File Size: " + str(filesize) + "\n" +  "Upload Time: " + eventTime + "\n" + "User Details: " + source + "\n" + "content of the csv file :" + emailcontent
    ses = boto3.client('ses')
    ses.send_email(Source = email_from,
        Destination = {'ToAddresses': [email_to,],}, 
            Message = {'Subject': {'Data': email_subject}, 'Body':{'Text' : {'Data': email_body}}}
            )
    print('Function execution Completed')

я не знаю, что я сделал не так, потому что часть, когда я просто получаю информацию о файле, работает нормально, когда я добавляю часть для чтения, лямбда-функция ничего не возвращает

Ответы на вопрос(1)

Решение Вопроса

а самом деле ваша лямбда-функция ничего не возвращает, но вы можете увидеть вывод вашего журнала в Cloudwatch. Я очень рекомендую использоватьlogger.info(message) вместоprint когда вы настраиваетеlogger.

Я надеюсь, что это поможет отладить вашу функцию.

За исключением части отправки, я переписываю ее (только что протестировано в консоли AWS):

import logging
import boto3

logger = logging.getLogger()
logger.setLevel(logging.INFO)

s3 = boto3.client('s3')

def lambda_handler(event, context):
    email_content = ''

    # retrieve bucket name and file_key from the S3 event
    bucket_name = event['Records'][0]['s3']['bucket']['name']
    file_key = event['Records'][0]['s3']['object']['key']
    logger.info('Reading {} from {}'.format(file_key, bucket_name))
    # get the object
    obj = s3.get_object(Bucket=bucket_name, Key=file_key)
    # get lines inside the csv
    lines = obj['Body'].read().split(b'\n')
    for r in lines:
       logger.info(r.decode())
       email_content = email_content + '\n' + r.decode()
    logger.info(email_content)
 ner25 окт. 2017 г., 16:36
Эй, братан, это действительно помогло, спасибо большое, я получил ответ, в моем коде я написал два s3 ​​= boto3.resource (u's3 ') s3 = boto3.client (' s3 ') это был ошибка.
 nicor8806 апр. 2018 г., 11:34
Хороший вопрос, я перенес инициализацию клиента s3 за пределы лямбда-обработчика
 jpact26 мар. 2018 г., 22:52
Небольшое улучшение - лучше инициализировать соединения с базой данных, sdks и т. Д. Из функции-обработчика (на глобальном уровне). Лямбда-сервис сохраняет контекст функции, поэтому последующие вызовы выполняются намного быстрее - больше на:docs.aws.amazon.com/lambda/latest/dg/best-practices.html

Ваш ответ на вопрос