如何在无服务器 Lambda 中下载 S3 文件 (Python)
how to download S3 file in Serverless Lambda (Python)
我在 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 存储桶
欢迎任何建议。
如果需要将对象下载到磁盘,可以使用tempfile
和download_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
请注意,512 MB limit 关于 Lambda 中临时文件的大小。
我认为更好的方法是在内存中处理它。您可以以非常相似的方式使用 io
而不是 tempfile
:
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 或内存。
在我的一个项目中,我将 webp 文件转换为 jpg。我可以参考下面的githublink来了解一下:
https://github.com/adjr2/webp-to-jpg/blob/master/codes.py
您可以直接在lambda函数中访问您下载的文件。我不确定你是否可以创建一个新文件夹(即使我对所有这些东西都很陌生)但你肯定可以操作文件并上传回相同(或不同)的 s3 存储桶。
希望对您有所帮助。
干杯!
我在 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 存储桶
欢迎任何建议。
如果需要将对象下载到磁盘,可以使用tempfile
和download_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
请注意,512 MB limit 关于 Lambda 中临时文件的大小。
我认为更好的方法是在内存中处理它。您可以以非常相似的方式使用 io
而不是 tempfile
:
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 或内存。
在我的一个项目中,我将 webp 文件转换为 jpg。我可以参考下面的githublink来了解一下:
https://github.com/adjr2/webp-to-jpg/blob/master/codes.py
您可以直接在lambda函数中访问您下载的文件。我不确定你是否可以创建一个新文件夹(即使我对所有这些东西都很陌生)但你肯定可以操作文件并上传回相同(或不同)的 s3 存储桶。
希望对您有所帮助。 干杯!