【问题标题】:How can I get the key of a downloaded S3 object using boto3 in Python?如何在 Python 中使用 boto3 获取下载的 S3 对象的密钥?
【发布时间】:2021-10-11 17:37:35
【问题描述】:

我从 S3 下载了一个文件,并将 S3 响应对象传递给其他函数。

我假设密钥/文件名必须存储在该对象本身的某个位置,但我似乎找不到它。我不想将文件名传递给每个需要它的函数。

我所有的谷歌搜索只是展示了如何在不下载的情况下从存储桶中获取文件名,而不是如何从响应中获取文件名。

我正在使用 Python/Boto3:

def main():
    file = s3.Object("my cool bucket", "my cool file").get()
    process_file(file)

def process_file(file):
    print(file.name) 
    # how do I make this work w/o passing in filename as arg to original function

【问题讨论】:

  • 您使用什么代码下载文件?如果您分享您的代码,我们绝对可以提供帮助 - 推荐阅读:stackoverflow.com/help/minimal-reproducible-example
  • 另外,如果您是下载它的人,那么您已经使用密钥下载了它——您真正想要达到什么目的?
  • 下载后,我将文件传递给新函数。我可以将文件名连同它一起传递,但这似乎很愚蠢——这肯定是某处对象的一部分吗?
  • 生成一个最小的例子并不重要——这是一个应该通过文档回答的技术问题,但我找不到它。
  • 我了解 - 它是 Python 文件对象还是 S3 响应对象?这就是我询问代码的原因。

标签: amazon-web-services amazon-s3 boto3


【解决方案1】:

get_object(...) 的响应确实返回响应对象中的键(“文件名”)。

它返回以下属性,这些都不是关键。

不幸的是,您必须首先将用于获取对象的密钥/文件名传递给需要它的任何其他函数。

{
    'Body': StreamingBody(),
    'DeleteMarker': True|False,
    'AcceptRanges': 'string',
    'Expiration': 'string',
    'Restore': 'string',
    'LastModified': datetime(2015, 1, 1),
    'ContentLength': 123,
    'ETag': 'string',
    'MissingMeta': 123,
    'VersionId': 'string',
    'CacheControl': 'string',
    'ContentDisposition': 'string',
    'ContentEncoding': 'string',
    'ContentLanguage': 'string',
    'ContentRange': 'string',
    'ContentType': 'string',
    'Expires': datetime(2015, 1, 1),
    'WebsiteRedirectLocation': 'string',
    'ServerSideEncryption': 'AES256'|'aws:kms',
    'Metadata': {
        'string': 'string'
    },
    'SSECustomerAlgorithm': 'string',
    'SSECustomerKeyMD5': 'string',
    'SSEKMSKeyId': 'string',
    'BucketKeyEnabled': True|False,
    'StorageClass': 'STANDARD'|'REDUCED_REDUNDANCY'|'STANDARD_IA'|'ONEZONE_IA'|'INTELLIGENT_TIERING'|'GLACIER'|'DEEP_ARCHIVE'|'OUTPOSTS',
    'RequestCharged': 'requester',
    'ReplicationStatus': 'COMPLETE'|'PENDING'|'FAILED'|'REPLICA',
    'PartsCount': 123,
    'TagCount': 123,
    'ObjectLockMode': 'GOVERNANCE'|'COMPLIANCE',
    'ObjectLockRetainUntilDate': datetime(2015, 1, 1),
    'ObjectLockLegalHoldStatus': 'ON'|'OFF'
}

【讨论】:

  • 这看起来很傻,但至少我没有疯。谢谢!
  • 实际上很愚蠢,我希望他们返回它,但您很少需要完整的响应 - 创建一个数据传输对象,然后在您自己的包含文件名的包装器中移动它 -这样,您就不需要将它作为额外参数传递给每个函数。别客气! :)
【解决方案2】:

您可以使用以下代码分别获取路径和文件名:

bkt_obj = conn_s3.Bucket(bkt_name)
for obj in bkt_obj.objects.all():
    if obj.key[-1] != '/' and obj.key[-1] != '$':
        file = obj.key
        path, filename = os.path.split(obj.key)
        filename = os.path.basename(file)
        print(f"FILE: {obj.key} -> {path}  -> {filename}")

输出:

FILE: dir1/dir1_file.txt -> dir1  -> dir1_file.txt
FILE: mydatafile.csv ->   -> mydatafile.csv

你可以在上面的代码后面加上你想得到下载文件的确切路径:

path_local_files='/home/user/s3_data/'
dest_file = os.path.join(path_local_files, filename)
print(f" --------> {dest_file}")  #use this variable if need of full path
#bkt_obj.download_file(obj.key, dest_file) #download file

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 2017-11-19
    • 1970-01-01
    • 2018-05-21
    • 2021-06-23
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多