AWS Lambda Python 文件夹处理
AWS Lambda Python folder handling
我正在创建我的第一个 AWS Lambda 图像优化器脚本,它在原始存储桶 'root' 的图像上运行良好。
我有三个桶。 'mybucket' 保留我要调整大小的原始现有图像。我决定将它们复制到 'mybucket-photos',它有一个 python lambda 函数监视它。 Lammda 函数优化传入的照片并保存到 'mybucket-photosresized' .
但是,当我尝试将 mybucket 的内容复制到 mybucket-photos 时,我在 python 脚本文件处理和 'subfolder' 密钥部分方面失败。
失败示例:
没有这样的文件或目录:'/tmp/91979758-51b3-44df-b2b1-d9eeddeb0802saddles/thumb/27dfahl/16-5-dk-dressage-saddle-for-sale/saddle_photo02_300.3a38de5F': IOError
我的问题是带有斜杠的文件夹名称导致了问题。我知道 'folder' 是密钥的一部分。
顺便说一句,我不完全理解处理程序方法在处理记录、存储桶和密钥方面的作用,这让我更加困惑。我天真的直觉是以某种方式替换 / 并在保存时将其添加回去。
python是:
from __future__ import print_function
import boto3
import os
import sys
import uuid
from PIL import Image
import PIL.Image
s3_client = boto3.client('s3')
def resize_image(image_path, resized_path):
with Image.open(image_path) as image:
image.save(resized_path,optimize=True)
def handler(event, context):
for record in event['Records']:
bucket = record['s3']['bucket']['name']
key = record['s3']['object']['key']
download_path = '/tmp/{}{}'.format(uuid.uuid4(), key)
upload_path = '/tmp/resized-{}'.format(key)
s3_client.download_file(bucket, key, download_path)
resize_image(download_path, upload_path)
s3_client.upload_file(upload_path, '{}resized'.format(bucket), key)
在此脚本中处理 'folders' 的最佳方法是什么?
您正在将对象从 S3 下载到机器上的本地文件夹 运行 您的 Lambda 函数。那台机器(几乎可以肯定)有一个 Linux 文件系统。您通常无法将文件写入此类文件系统上的文件夹,除非该文件夹已经存在。我没有看到您的代码试图创建用于保存下载对象的文件夹。
您还通过将下载对象的密钥绑定到您的下载文件夹名称中,使这变得更加复杂。
因此,要么简单地下载到 /tmp/ 或 /tmp/downloads/(您预先创建的),要么继续下载到包含 S3 对象密钥名称的文件夹 但是 在这种情况下,您必须预先创建相关的文件夹层次结构。
就像在常规平台上编码一样,没有必要使用文件系统,除非对象大于 RAM 和交换 - 而是在内存对象中使用。在处理图像时,无论如何都必须有足够的内存(RAM + Swap)来处理它。这样速度更快,更不容易出错。
PIL 的 Image.open()
接受一个文件对象,boto 的 s3_client.get_object()['Body']
returns 接受一个内存中的文件对象。不幸的是,boto 对象不支持 seek()
所以不太可能工作。相反,将 Image.fromstring()
与响应正文中的字节一起使用:
s3_object = s3_client.get_object(Bucket=bucket, Key=key)
file_obj = s3_object['Body']
file_contents = file_obj.read()
pil_image = Image.fromstring(file_contents)
如果您必须使用文件系统,请使用 Python 的 tempfile.TemporaryFile
为您创建临时文件。
我的原代码是aws提供的。我认为他们选择将文件保存到文件系统是因为您需要保存图像以使用优化等方法更改它们
我决定坚持原来的代码,用正则表达式去掉路径和文件名。它似乎足以满足我的需求。我确实注意到一些问题,在后台出现一些错误,文件缺少扩展名等。
from __future__ import print_function
import boto3
import os
import sys
import uuid
from PIL import Image
import PIL.Image
import re
s3_client = boto3.client('s3')
def resize_image(image_path, resized_path):
with Image.open(image_path) as image:
image.save(resized_path,optimize=True)
def handler(event, context):
for record in event['Records']:
bucket = record['s3']['bucket']['name']
key = record['s3']['object']['key']
file_name_pattern = re.match( r'(.*?([^/]+)/?)$',str(key))
file_name = file_name_pattern.group(2)
path_without_name = file_name_pattern.group(1)
download_path = '/tmp/{}{}'.format(uuid.uuid4(), file_name)
upload_path = '/tmp/resized-{}'.format(file_name)
s3_client.download_file(bucket, key, download_path)
resize_image(download_path, upload_path)
s3_client.upload_file(upload_path, '{}resized'.format(bucket), str(key))
我正在创建我的第一个 AWS Lambda 图像优化器脚本,它在原始存储桶 'root' 的图像上运行良好。
我有三个桶。 'mybucket' 保留我要调整大小的原始现有图像。我决定将它们复制到 'mybucket-photos',它有一个 python lambda 函数监视它。 Lammda 函数优化传入的照片并保存到 'mybucket-photosresized' .
但是,当我尝试将 mybucket 的内容复制到 mybucket-photos 时,我在 python 脚本文件处理和 'subfolder' 密钥部分方面失败。
失败示例:
没有这样的文件或目录:'/tmp/91979758-51b3-44df-b2b1-d9eeddeb0802saddles/thumb/27dfahl/16-5-dk-dressage-saddle-for-sale/saddle_photo02_300.3a38de5F': IOError
我的问题是带有斜杠的文件夹名称导致了问题。我知道 'folder' 是密钥的一部分。
顺便说一句,我不完全理解处理程序方法在处理记录、存储桶和密钥方面的作用,这让我更加困惑。我天真的直觉是以某种方式替换 / 并在保存时将其添加回去。
python是:
from __future__ import print_function
import boto3
import os
import sys
import uuid
from PIL import Image
import PIL.Image
s3_client = boto3.client('s3')
def resize_image(image_path, resized_path):
with Image.open(image_path) as image:
image.save(resized_path,optimize=True)
def handler(event, context):
for record in event['Records']:
bucket = record['s3']['bucket']['name']
key = record['s3']['object']['key']
download_path = '/tmp/{}{}'.format(uuid.uuid4(), key)
upload_path = '/tmp/resized-{}'.format(key)
s3_client.download_file(bucket, key, download_path)
resize_image(download_path, upload_path)
s3_client.upload_file(upload_path, '{}resized'.format(bucket), key)
在此脚本中处理 'folders' 的最佳方法是什么?
您正在将对象从 S3 下载到机器上的本地文件夹 运行 您的 Lambda 函数。那台机器(几乎可以肯定)有一个 Linux 文件系统。您通常无法将文件写入此类文件系统上的文件夹,除非该文件夹已经存在。我没有看到您的代码试图创建用于保存下载对象的文件夹。
您还通过将下载对象的密钥绑定到您的下载文件夹名称中,使这变得更加复杂。
因此,要么简单地下载到 /tmp/ 或 /tmp/downloads/(您预先创建的),要么继续下载到包含 S3 对象密钥名称的文件夹 但是 在这种情况下,您必须预先创建相关的文件夹层次结构。
就像在常规平台上编码一样,没有必要使用文件系统,除非对象大于 RAM 和交换 - 而是在内存对象中使用。在处理图像时,无论如何都必须有足够的内存(RAM + Swap)来处理它。这样速度更快,更不容易出错。
PIL 的 Image.open()
接受一个文件对象,boto 的 s3_client.get_object()['Body']
returns 接受一个内存中的文件对象。不幸的是,boto 对象不支持 seek()
所以不太可能工作。相反,将 Image.fromstring()
与响应正文中的字节一起使用:
s3_object = s3_client.get_object(Bucket=bucket, Key=key)
file_obj = s3_object['Body']
file_contents = file_obj.read()
pil_image = Image.fromstring(file_contents)
如果您必须使用文件系统,请使用 Python 的 tempfile.TemporaryFile
为您创建临时文件。
我的原代码是aws提供的。我认为他们选择将文件保存到文件系统是因为您需要保存图像以使用优化等方法更改它们
我决定坚持原来的代码,用正则表达式去掉路径和文件名。它似乎足以满足我的需求。我确实注意到一些问题,在后台出现一些错误,文件缺少扩展名等。
from __future__ import print_function
import boto3
import os
import sys
import uuid
from PIL import Image
import PIL.Image
import re
s3_client = boto3.client('s3')
def resize_image(image_path, resized_path):
with Image.open(image_path) as image:
image.save(resized_path,optimize=True)
def handler(event, context):
for record in event['Records']:
bucket = record['s3']['bucket']['name']
key = record['s3']['object']['key']
file_name_pattern = re.match( r'(.*?([^/]+)/?)$',str(key))
file_name = file_name_pattern.group(2)
path_without_name = file_name_pattern.group(1)
download_path = '/tmp/{}{}'.format(uuid.uuid4(), file_name)
upload_path = '/tmp/resized-{}'.format(file_name)
s3_client.download_file(bucket, key, download_path)
resize_image(download_path, upload_path)
s3_client.upload_file(upload_path, '{}resized'.format(bucket), str(key))