在python中为S3文件夹创建预签名的url

时间:2019-06-25 06:59:37

标签: python-3.x amazon-web-services url amazon-s3 boto3

我正在尝试生成S3文件夹(其本身包含更多文件夹/文件)的预签名url,并将其分发到我的客户端之间,以便他们可以下载其内容。即,通过单击链接,用户会将文件夹下载到其本地磁盘。

但是,在XML对话中,我总是收到“没有这样的键”错误。

我正在使用boto3 sdk中的client.generate_presigned_url()

def create_presigned_url(bucket, object):
    try:
        url = s3_client.generate_presigned_url(
            'get_object',
            Params={
                'Bucket': bucket,
                'Key': object
            },
            ExpiresIn=240,
            HttpMethod='GET'
        )
    except ClientError as e:
        print(e)
        return None
    return url

这是错误消息:

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
   <Code>NoSuchKey</Code>
      <Message>The specified key does not exist.</Message>
         <Key>output/BARNES/070419/APR19BAR/</Key>
         <RequestId>E6BE736FE945FA22</RequestId>
         <HostId>
      hk3+d+***********************************************************+EO2CZmo=
          </HostId>
</Error>

3 个答案:

答案 0 :(得分:3)

S3没有“文件夹”的概念。您实际上要在这里尝试做的是为multiple keys创建一个预签名的url,这也是不可能的。如果您绝对必须为多个文件共享一个URL,则需要将它们压缩到一个对象中,然后使用预签名的URL共享该对象的密钥。

答案 1 :(得分:1)

import boto3

s3_client = boto3.client(
    's3',
    region_name='your_region_name',
    aws_access_key_id='your_aws_access_key_id',
    aws_secret_access_key='your_aws_access_key_id',
)

# Just specify folder_name:
url = s3_client.generate_presigned_url(
    ClientMethod='put_object',
    Params={'Bucket': 'your_bucket_name', 'Key': 'folder_name/file_name.txt',},
    ExpiresIn=60,
)

答案 2 :(得分:0)

生成的URL将在一周后过期。

由于AWS的限制:您最多可以保留一个星期的链接。
大约是600000秒(请参阅ExpiresIn)。

def create_presigned_url(bucket, object):
    try:
        bucket_name = bucket
        ACCESS_KEY = "access_key"
        SECRET_KEY = "secret_key"
        key = object
        location = boto3.client('s3', aws_access_key_id=ACCESS_KEY,aws_secret_access_key=SECRET_KEY).get_bucket_location(Bucket=bucket_name)['LocationConstraint']
        s3_client = boto3.client(
                's3',
                region_name=location,
                aws_access_key_id=ACCESS_KEY,
                aws_secret_access_key=SECRET_KEY,
            )
        url = s3_client.generate_presigned_url(
                ClientMethod='get_object',
                Params={'Bucket': bucket_name, 'Key': key, },
                ExpiresIn=600000,
            )
    except ClientError as e:
        print(e)
        return None
    return url