如何在无服务器 Lambda (Python) 中下载 S3 文件

Pho*_* Vu 5 python boto3 aws-lambda serverless-framework

我在 Python 中创建了一个 lambda(使用 Serverless),它将由 SQS 消息触发。

处理程序

s3 = boto3.resource('s3')

def process(event, context):
    response = None
    # for record in event['Records']:
    record = event['Records'][0]
    message = dict()
    try:
        message = json.loads(record['body'])

        s3.meta.client.download_file(const.bucket_name, 'class/raw/photo/' + message['photo_name'], const.raw_filepath + message['photo_name'])    

        ...

        response = {
            "statusCode": 200,
            "body": json.dumps(event)
        }

    except Exception as ex:
        error_msg = 'JOB_MSG: {}, EXCEPTION: {}'.format(message, ex)
        logging.error(error_msg)

        response = {
                "statusCode": 500,
                "body": json.dumps(ex)
            }

    return response
Run Code Online (Sandbox Code Playgroud)

常量文件

bucket_name = 'test'
raw_filepath = '/var/task/raw/'
Run Code Online (Sandbox Code Playgroud)

我创建了一个文件夹“raw”,与文件 handler.py 相同,然后部署无服务器 lambda。

触发 lambda 时出现错误(来自 CloudWatch)。

No such file or directory: u'/var/task/raw/Student001.JPG.94BBBAce'
Run Code Online (Sandbox Code Playgroud)

据我了解,无法访问 lambda 文件夹或无法在 lambda 中创建文件夹。

为了最佳实践,我分享了 lambda 的目标:

  • 下载 S3 原始文件
  • 调整文件大小并将新文件上传到另一个 S3 存储桶

任何建议表示赞赏。

Mil*_*mak 7

如果需要将对象下载到磁盘,可以使用tempfiledownload_fileobj保存它:

import tempfile

with tempfile.TemporaryFile() as f:
    s3.meta.client.download_fileobj(const.bucket_name, 
                                   'class/raw/photo/' + message['photo_name'],
                                    f)
    f.seek(0)
    # continue processing f
Run Code Online (Sandbox Code Playgroud)

请注意,Lambda 中临时文件的大小有512 MB 的限制

我认为更好的方法是在内存中处理它。而不是tempfile,您可以io以非常相似的方式使用:

import io

data_stream = io.BytesIO()
s3.meta.client.download_fileobj(const.bucket_name, 
                               'class/raw/photo/' + message['photo_name'],
                                data_stream)
data_stream.seek(0)
Run Code Online (Sandbox Code Playgroud)

这样,数据不需要写入磁盘,a) 更快,b) 您可以处理更大的文件,基本上直到您达到 Lambda 的 3008 MB 内存限制或内存。