如何在Python 3中重新编码S3键的AWS Lambda事件编码?

7

我正在编写一个Python 3的AWS Lambda例程,该例程将从Lambda事件对象中获取S3存储桶和Key(source_key),并将文件复制到具有相同键值(Destination_key)的另一个S3存储桶。

然而,事件对象中的S3 Key是以一种编码方式进行编码的,因此当我使用source_key值写入目标存储桶时,S3会抛出404错误。

S3 Lambda事件对象返回的Key:

'object': {'key': 'SBN-Fwd_+USPS+-+Springdale%2C+OH+-+Mail+Processing+Facility+-+Bid+Extension+Notice.eml' 

提交 S3 的 'key' 值时出现错误:

{'Error': {'Code': 'NoSuchKey', 'Message': 'The specified key does not exist.', 'Key': 'SBN-Fwd_+USPS+-+Springdale%2C+OH+-+Mail+Processing+Facility+-+Bid+Extension+Notice.eml'}, 'ResponseMetadata': {'RequestId': '2C0154D58032B5B4', 'HostId': 'zxp56SHdODohW5ln8B5GOW+YPqGfL4/kJGD+qV46yMhLZU92BrOC/hlh/HPHywAuGuJiICL0RFk=', 'HTTPStatusCode': 404, 'HTTPHeaders': {'x-amz-request-id': '2C0154D58032B5B4', 'x-amz-id-2': 'zxp56SHdODohW5ln8B5GOW+YPqGfL4/kJGD+qV46yMhLZU92BrOC/hlh/HPHywAuGuJiICL0RFk=', 'content-type': 'application/xml', 'transfer-encoding': 'chunked', 'date': 'Thu, 20 Sep 2018 16:40:00 GMT', 'server': 'AmazonS3'}, 'RetryAttempts': 0}}

我只是使用了boto3库,将源文件的位置(source_key)复制到不同的存储桶(destination_key)中。

 copy_source = {'Bucket': source_bucket, 'Key': source_key}
 destination_key = source_key

 s3resource.copy(copy_source ,destination_bucket, destination_key)

只要源键(source_key)不包含任何奇怪字符(空格,逗号等),这个例程就能正常工作。
我该如何处理源键(source_key),使其与目标键(destination key)兼容?我无法找到有关S3期望的编码的任何文档。
1个回答

9

事件消息中的S3键是URL编码的。来自AWS文档

s3键提供有关涉及事件的存储桶和对象的信息。对象键名称值已进行URL编码。例如,“red flower.jpg”变为“red+flower.jpg”(Amazon S3在响应中返回“application/x-www-form-urlencoded”作为内容类型)。

为了正确重用桶和键,您需要对它们进行解码。在Python(>=3.5)中,您可以使用unquote_plus函数进行解码。

from urllib.parse import unquote_plus 

copy_source = {'Bucket': source_bucket, 'Key': source_key}
destination_bucket = unquote_plus(source_bucket, encoding='utf-8')
destination_key = unquote_plus(source_key, encoding='utf-8')

s3resource.copy(copy_source ,destination_bucket, destination_key)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接