【问题标题】:How to read content from the s3 bucket as url如何从 s3 存储桶中读取内容作为 url
【发布时间】:2020-12-16 12:16:01
【问题描述】:

下面是我的 s3 存储桶 url

s3_filename 是s3://xx/xx/y/z/ion.csv

如果它是桶,我可以像下面的代码一样阅读

def read_s3(bucket, key):
        s3 = boto3.client('s3')
        obj = s3.get_object(Bucket=bucket, Key=key)
        df = pd.read_csv(obj['Body'])
        return df

【问题讨论】:

  • 您的代码有什么问题吗?
  • @deadshot 我的代码将从不带 URL 的 usng 存储桶名称中读取
  • 你有什么问题?

标签: python amazon-s3 aws-lambda


【解决方案1】:

由于您似乎在使用 Pandas,请注意它实际上在封面下使用了s3fs。因此,如果您的安装是相对较新且标准的,您可以直接这样做:

df = pd.read_csv(s3_path)

如果您的存储桶有一些特定配置,例如特殊凭据、KMS 加密等,您可以使用显式配置的s3fs 文件系统,例如:

fs = s3fs.S3FileSystem(
    key=my_aws_access_key_id,
    secret=my_aws_secret_access_key,
    s3_additional_kwargs={
            'ServerSideEncryption': 'aws:kms',
            'SSEKMSKeyId': my_kms_key,
    },
)
# note: KMS encryption only used when writing; when reading, it is automatic if you have access

with fs.open(s3_path, 'r') as f:
    df = pd.read_csv(f)

# here we write the same df at a different location, making sure
# it is using my_kms_key:
with fs.open(out_s3_path, 'w') as f:
    df.to_csv(f)

也就是说,如果您真的有兴趣自己处理获取对象,问题只是关于如何删除潜在的s3:// 前缀然后拆分bucket/key,您可以简单地使用:

bucket, key = re.sub(r'^s3://', '', s3_path).split('/', 1)

但这可能会遗漏更多由系统处理的一般情况和约定,例如awscli 或上面提到的s3fs

为了更通用,您可以在awscli 中查看他们是如何做到这一点的。一般来说,这样做通常可以很好地表明某些功能是否已经内置在boto3botocore 中。然而,在这种情况下,它似乎不会(查看 release-1.18.126 的本地克隆)。他们只是从第一原则做到这一点:参见awscli.customizations.s3.utils.split_s3_bucket_key,因为它已实现here

从最终在该代码中使用的正则表达式,您可以推断出awscli 允许s3_path 的情况确实非常多样化:

_S3_ACCESSPOINT_TO_BUCKET_KEY_REGEX = re.compile(
    r'^(?P<bucket>arn:(aws).*:s3:[a-z\-0-9]+:[0-9]{12}:accesspoint[:/][^/]+)/?'
    r'(?P<key>.*)$'
)

【讨论】:

    猜你喜欢
    • 2019-09-19
    • 2016-07-12
    • 2020-08-29
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    相关资源
    最近更新 更多