【问题标题】:How to get a downloadable url of S3 bucket itself not an object url using python, boto3?如何使用 python、boto3 获取 S3 存储桶本身的可下载 url 而不是对象 url?
【发布时间】:2021-06-23 08:28:52
【问题描述】:

我有很多文件和子文件夹,其中有一些文件夹和文件,所有这些都在 S3 存储桶中。所以我知道如何下载文件,因为有一个对象 url 点击它,我们将能够下载文件。

要求

但我的要求是我需要一个 S3 存储桶的可下载 url,以便单击它,我将能够原样下载存储桶中的所有内容,例如文件、子文件夹等。

import os, boto3, params, subprocess

path  = "C:\\Users\\lenovo\\Desktop\\BackUp"

subprocess.run(['aws', 's3', 'sync', path, 's3://axis-tax-drive'])

我写了这段代码来上传内容到S3,现在我想得到一个上面提到的S3存储桶的可下载url。

是否可以通过创建接入点或类似的东西来满足要求..

我想知道所有的可能性。

请帮忙..

提前致谢。

【问题讨论】:

  • 没有“S3 存储桶的可下载 url”这样的概念。 Amazon S3 是一种对象存储服务。您可以下载单个对象,但不能下载整个存储桶。您可能想要使用 AWS CLI(根据您的示例),它可以上传/下载对象,但它只是单独复制对象。
  • @John Rotenstein Max-Raba-Streicher 提到的任何方法都可以吗?
  • 你能准确描述你真正想要实现的目标吗?
  • @John Rotenstein 没什么复杂的 John,只是一个 S3 存储桶的 URL,通过点击我就可以完整地下载存储桶的所有内容。
  • @John Rotenstein 就像对象 url 如何让我下载对象一样,我需要 S3 url 来下载 S3 存储桶。

标签: python amazon-web-services amazon-s3 boto3 aws-cli


【解决方案1】:

【讨论】:

  • @Max-Raba_Streicher 我不想要对象的 URL,而是想要存储桶本身的可下载 url,这样我就可以下载存储桶或其中的内容,无论是否存在只需单击 url 即可在该存储桶中创建子文件夹或文件。
  • @CharliePuth 整个存储桶是 zip 吗?然后你需要编程一些东西,例如通过 API 网关在 lambda 中。公开的时候需要配置成网站,大家可以下载docs.aws.amazon.com/AmazonS3/latest/userguide/…
  • @ Max-Raba-Streicher 如果您能详细说明一下 lambda API 网关方法,我会很高兴
【解决方案2】:

无法“从 URL 下载存储桶”。 Amazon S3 的 API 调用只能下载单个对象。也不可能要求 S3 提供存储在 S3 中的多个文件的 Zip。

但是,您可以使用AWS Command-Line Interface (CLI) 来执行此操作...

您的代码显示了使用 AWS CLI 的示例:

aws s3 sync <path> s3://bucketname

AWS CLI 是一个调用 S3 API 的 Python 程序。对于上述命令,它会列出path 的内容,然后使用循环调用PutObject() 命令一次上传一个文件。但是,它有点聪明,因为它使用多线程同时上传多个文件(但每次上传都是通过单独的 API 调用完成的)。

您可以使用反向使用相同的命令将存储桶下载到您的计算机:

aws s3 sync s3://bucketname <path>

或者,您可以编写自己的程序来遍历文件并单独下载它们。

【讨论】:

    【解决方案3】:

    这将是 API Gateway / Lambda 方法。

    假设您有一个 Lambda,它从您的 S3 存储桶中下载所有对象并将其放入一个 zip 中,如下所示:

    import logging
    import os
    from io import BytesIO
    from typing import Dict, Any
    from zipfile import ZipFile
    
    import boto3
    
    LOGGER = logging.getLogger("zip-bucket")
    logging.basicConfig(level="INFO",)
    '''
      this is the method which is invoked by the lambda. if you upload it AWS lambda, this is your method which will be called.
      not quite sure about what is in the event, but I do not need it for now.
    '''
    def handle(event: Dict[str, Any], context: Dict[str, Any]):
        s3 = boto3.client("s3")
        bucket = os.environ["BUCKET"]
        s3_objects = s3.list_objects(Bucket=bucket)
        zip_buffer = BytesIO()
        with ZipFile(zip_buffer, 'w') as myzip:
            for s3_object in s3_objects['Contents']:
                key = s3_object['Key']
                LOGGER.info("Zipping %s", key)
                myzip.writestr(key, s3.get_object(Bucket=bucket, Key=key)['Body'].read())
        myzip.close()
        return {
                'headers': { "Content-Type": " application/zip; charset=binary" },
                'statusCode': 200,
                'body': zip_buffer.getvalue(),
                'isBase64Encoded': False
            }
    
    
    
    if __name__ == '__main__':
        zipfile = open("result.zip", "wb")
        zipfile.write(handle(None, None)['body'])
        zipfile.close()
    

    您可以在本地运行它进行测试,也可以创建一个 AWS lambda。由于唯一的依赖是提供的 aws-sdk (boto3),它开箱即用。请记住,您必须将 lambda 执行角色权限授予您的 s3 存储桶(ListBucket 和 GetObject)。 现在您的请求处理逻辑已经到位。现在缺少的是某种 HTTP 端点。 API 网关在这里发挥作用。

    在 AWS 中,转到 API 网关并创建一个 HTTP 网关,因为这是最简单的一个。您可以在创建新 api 时连接先前创建的 lambda。如果您通过 AWS 控制台执行此操作,它将在您的 lambda 中即时创建策略。 之后,您将获得一个 http 端点,您可以在其中下载 zip。如果它不起作用,您需要查看 Cloudwatch 日志或 lambda 或您的 api 网关。

    此链接可能对您很感兴趣:https://docs.aws.amazon.com/apigateway/latest/developerguide/lambda-proxy-binary-media.html

    请记住,该方法没有内置身份验证!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-01
      • 1970-01-01
      • 2020-05-26
      • 1970-01-01
      • 1970-01-01
      • 2017-11-17
      • 1970-01-01
      • 2018-01-04
      相关资源
      最近更新 更多