【问题标题】:how to download S3 file in Serverless Lambda (Python)如何在 Serverless Lambda (Python) 中下载 S3 文件
【发布时间】:2019-06-14 21:11:58
【问题描述】:

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

handler.py

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

const.py

bucket_name = 'test'
raw_filepath = '/var/task/raw/'

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

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

No such file or directory: u'/var/task/raw/Student001.JPG.94BBBAce'

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

就最佳实践而言,我分享 lambda 的目标:

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

欢迎提出任何建议。

【问题讨论】:

    标签: python aws-lambda boto3 serverless-framework


    【解决方案1】:

    在我的一个项目中,我将 webp 文件转换为 jpg。我可以参考下面的github链接来了解一下:

    https://github.com/adjr2/webp-to-jpg/blob/master/codes.py

    您可以在 lambda 函数中直接访问您下载的文件。我不确定你是否可以创建一个新文件夹(即使我对所有这些东西都很陌生)但你肯定可以操纵文件并上传回相同(或不同)的 s3 存储桶。

    希望对您有所帮助。 干杯!

    【讨论】:

      【解决方案2】:

      如果需要将对象下载到磁盘,可以使用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
      

      请注意,Lambda 中的临时文件大小有一个512 MB limit

      我认为更好的方法是在内存中处理它。除了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)
      

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

      【讨论】:

      • 对于我的方法,我需要使用 read()“执行”data_stream:package.my_method(data_stream.read())
      猜你喜欢
      • 1970-01-01
      • 2017-05-25
      • 2021-06-16
      • 2015-12-07
      • 1970-01-01
      • 2020-04-10
      • 2018-08-29
      • 2018-09-01
      • 2018-12-31
      相关资源
      最近更新 更多