我有一個 Lambda 函式,用于將基于存盤桶上的 PUT 事件的某種檔案格式復制到另一個存盤桶。CloudWatch 日志中不會引發任何錯誤,但代碼不會復制檔案。這只發生在按日期磁區的密鑰上。
拉姆達事件
{
"Records": [
{
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "lasic2-artifacts",
"bucket": {
"name": "BUCKETNAME",
"arn": "arn:aws:s3:::BUCKETNAME"
},
"object": {
"key": "models/operatorai-model-store/lasic2/2022/03/08/10:21:05/artifacts.tar.gz"
}
}
}
]
}
Lambda 函式
import boto3
from botocore.exceptions import ClientError
print("Loading function")
s3 = boto3.client("s3", region_name="us-east-1")
class NoRecords(Exception):
"""
Exception thrown when there are no records found from
s3:ObjectCreatedPut
"""
def get_source(bucket, key):
"""
Returns the source object to be passed when copying over the contents from
bucket A to bucket B
:param bucket: name of the bucket to copy the key to
:param key: the path of the object to copy
"""
return {
"Bucket": bucket,
"Key": key,
}
def process_record(
record,
production_bucket,
staging_bucket,
):
"""
Process individual records(example record can be found here
https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html#test-manual-invoke)
:param record: a record from s3:ObjectCreated:Put
:param production_bucket: name of the production bucket which comes from
the records
:param staging_bucket: name of the staging bucket to save the key from the
production_bucket into
"""
key = record["s3"]["object"]["key"]
print(f"Key: \n{key}")
try:
s3_response = s3.get_object(Bucket=production_bucket, Key=key)
s3_object = s3_response["Body"].read()
copy_source = get_source(bucket=production_bucket, key=key)
s3.copy_object(
Bucket=staging_bucket,
Key=key,
CopySource=copy_source,
ACL="bucket-owner-full-control",
)
except ClientError as error:
error_code = error.response["Error"]["Code"]
error_message = error.response["Error"]["Message"]
if error_code == "NoSuchBucket":
print(error_message)
raise
except Exception as error:
print(f"Failed to upload {key}")
print(error)
raise
def lambda_handler(event, _):
print(f"Event: \n{event}")
records = event["Records"]
num_records = len(records)
if num_records == 0:
raise NoRecords("No records found")
record = records[0]
production_bucket = record["s3"]["bucket"]["name"]
staging_bucket = f"{production_bucket}-staging"
process_record(
record=record,
production_bucket=production_bucket,
staging_bucket=staging_bucket,
)
uj5u.com熱心網友回復:
如果您收到以下問題,則提示問題:
"key": "models/operatorai-model-store/lasic2/2022/03/08/10:21:05/artifacts.tar.gz"
您可以看到此處的物件鍵已編碼。檔案對此很明確:
s3 鍵提供有關事件中涉及的存盤桶和物件的資訊。物件鍵名值是 URL 編碼的。例如,“redflower.jpg”變為“red flower.jpg”(Amazon S3 在回應中回傳“application/x-www-form-urlencoded”作為內容型別)。
由于您可以在 boto3 中使用的所有 SDK API 都需要一個未編碼的字串,因此您需要在物件密鑰進入 Lambda 時對其進行解碼,然后才能使用它:
import urllib.parse
# ....
key = record["s3"]["object"]["key"]
key = urllib.parse.unquote_plus(key)
print(f"Key: \n{key}")
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/454790.html
