【发布时间】:2019-01-25 15:57:58
【问题描述】:
我正在编写一个 lambda 函数,每次用户将图像上传到 S3 时都会触发该函数。该函数的主要目的是压缩图像,也可能在此过程中对其进行重命名。实现这一点的功能是获取新上传的图片,压缩,上传新压缩的图片,删除原文件:
@app.on_s3_event(bucket=settings.BUCKET_NAME, events=['s3:ObjectCreated:*'])
def compress(event):
# download the resource
s3.Bucket(settings.BUCKET_NAME).download_file(key, local_file_path)
# compress the image
...
# rename the file, if necessary (change extension, etc.)
...
# upload the new image
s3.Object(settings.BUCKET_NAME, output_path).put(Body=open(compressed_path, 'rb'))
# remove original image
s3.Object(settings.BUCKET_NAME, event.key).delete()
因此,如果我将名为 sample.png 的图像上传到 S3,它会被压缩并重命名为 sample.jpg;和sample.png 之后将被删除。
然而,问题在于解决方案将导致无限递归。原因是压缩图像的上传会再次调用lambda函数,从而导致再次下载,从而压缩已经压缩的图像,从而再次上传。广告无限。
我的一位朋友提出了两种可能的解决方案:缓存压缩图像的名称,将它们存储在单独的 S3 存储桶文件中的某个位置,并防止缓存的文件名被多次上传;并修改压缩图像的 exif/metada,以便 lambda 可以判断哪些文件已被压缩,指示该函数不应继续执行,这将防止再次发生压缩。
第一个想法很容易出现多个文件同时上传到服务器时可能出现的问题,至少理论上是这样。第二个想法可能需要第三方库,例如piexif,但这是我目前正在考虑的。
您有更好的方法来解决这个问题吗?还是我什至一开始就在做压缩的事情(除了递归上传和下载)?我的意思是,也许我可以压缩 S3 图像而无需执行下载-压缩-上传-删除例程。
【问题讨论】:
-
它总是会是 png -> jpg 转换吗?如果是这样,您可以使用 on_s3_event 的
suffix参数(请参阅chalice.readthedocs.io/en/latest/api.html#Chalice.on_s3_event)过滤掉不需要的对象创建事件。 -
有时 JPEG 也会被转换为 JPEG。
-
然后我建议将图像分成两个桶 - 原始和处理。您不必担心递归(或一般的输入),如果您将来需要重新处理它们,您可以保留原件(当然,我只是在编一个用例)。如果你想把它放在一个桶里,你把处理过的放在一个目录里,这样行吗?
-
这是一个不同的用例。上传者希望压缩图像与他上传原始图像的目录位于同一目录中,因为该路径将被不同的程序使用。
标签: python amazon-s3 aws-lambda chalice