我正在编写一个Python 3 AWS Lambda例程,该例程将从Lambda事件对象中获取S3存储桶和Key(source_key),然后将文件复制到具有相同Key值(Destination_key)的另一个S3存储桶。
但是,对事件对象中的S3键进行编码的方式是,当我使用source_key值写入目标存储桶时,S3会引发404错误。
S3 Lambda事件对象返回的键:
'object': {'key': 'SBN-Fwd_+USPS+-+Springdale%2C+OH+-+Mail+Processing+Facility+-+Bid+Extension+Notice.eml'
将“键”值提交回S3时出错:
{'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以确保它与目标密钥兼容?我找不到有关S3期望进行编码的任何文档。
答案 0 :(得分:1)
S3键是URL编码的。来自AWS documentation:
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)