如何从连接到 S3 存储桶的 SNS 中获取文件密钥

How to get file key out of an SNS connected to S3 Bucket

我在 AWS 上有两个不同的配置文件。 s3 存储桶和 SNS 在配置文件 A 中,我的 lambda 函数在配置文件 B 中。当新文件添加到 s3 存储桶时,SNS 会触发 lambda 函数。

lambda 函数然后应该访问新文件并使用 pandas 处理它。这是我现在正在做的事情;

    sts_connection = boto3.client('sts')
acct_b = sts_connection.assume_role(
    RoleArn="arn:aws:iam::**************:role/AllowS3AccessFromAccountB",
    RoleSessionName="cross_acct_lambda"
)

ACCESS_KEY = acct_b['Credentials']['AccessKeyId']
SECRET_KEY = acct_b['Credentials']['SecretAccessKey']
SESSION_TOKEN = acct_b['Credentials']['SessionToken']

s3 = boto3.client('s3', aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY, aws_session_token=SESSION_TOKEN)

path = get_file_path(event)
obj = s3.get_object(Bucket='my-bucket-name', Key=path)
csv_string = io.BytesIO(obj['Body'].read())

# Read a csv file and turn it into a DataFrame
df = pd.read_json(csv_string, delimiter=';', engine ='c', encoding= 'unicode_escape')

def get_file_path(event_body):
"""Function to get manifest path anc check if it is manifest"""
try:
    # Get message for first SNS record
    sns_message = json.loads(event_body["Records"][0]["Sns"]["Message"])
    path = sns_message["Records"][0]["s3"]["object"]["key"]
except TypeError as ex:
    logging.error("Unable to parse event: " + str(event_body))
    raise ex
return path

一切正常,直到 s3.get_object() 部分。我收到以下错误;

botocore.errorfactory.NoSuchKey: An error occurred (NoSuchKey) when calling the GetObject operation: The specified key does not exist.

也许我以错误的方式读取文件密钥?

编辑: 这是我调试时路径的样子。

svv/sensor%3D11219V22151/year%3D2020/month%3D03/day%3D02/test.csv

而s3文件结构是这样的;

sensor-data/sensor=*******/year=2020/month=03/day=02

看来我需要对等号使用正则表达式。但是应该有一个更通用的解决方案。

这是我在一些 Lambda 代码中的片段,它是 直接 由 Amazon S3(不是通过 Amazon SNS)触发的:

import urllib

key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'])

您可以尝试类似的解析,看是否正确了Key。