Python 3 Boto 3,AWS S3:获取对象URL

时间:2018-02-04 13:29:17

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

我需要在上传文件后直接检索公共对象URL,这样才能将其存储在数据库中。 这是我的上传代码:

   s3 = boto3.resource('s3')
   s3bucket.upload_file(filepath, objectname, ExtraArgs={'StorageClass': 'STANDARD_IA'})

我不是在寻找预先签名的网址,只是可以通过https公开访问的网址。

任何帮助表示感谢。

5 个答案:

答案 0 :(得分:3)

没有简单的方法,但您可以从存储桶所在的区域(get_bucket_location),存储桶名称和存储密钥构建URL:

bucket_name = "my-aws-bucket"
key = "upload-file"

s3 = boto3.resource('s3')
bucket = s3.Bucket(bucket_name)
bucket.upload_file("upload.txt", key)
location = boto3.client('s3').get_bucket_location(Bucket=bucket_name)['LocationConstraint']
url = "https://s3-%s.amazonaws.com/%s/%s" % (location, bucket_name, key)

答案 1 :(得分:2)

自2010年以来,您可以使用虚拟主机样式的S3网址,即,无需弄乱特定于区域的网址:

url = 'https://%s.s3.amazonaws.com/%s' % (bucket, key)

此外,在2020年9月30日或之前创建的存储桶继续支持路径样式模型(特定于区域的url)。在该日期之后创建的存储桶必须使用虚拟托管模型引用

另请参阅此blog post

答案 2 :(得分:0)

请注意。 函数调用

location = 
    boto3.client('s3').get_bucket_location(Bucket=bucket_name['LocationConstraint']
如果存储桶位于“ us-east-1”区域,则

可能返回location = None。因此,我将修改上述答案,并在该行下方添加一行:

if location == None: location = 'us-east-1'

答案 3 :(得分:0)

如果键中的某些特殊字符(例如:'+')串联原始键将失败,您必须将其引号:

url = "https://s3-%s.amazonaws.com/%s/%s" % (
    location,
    bucket_name,
    urllib.parse.quote(key, safe="~()*!.'"),
)

或者您可以致电:

my_config = Config(signature_version = botocore.UNSIGNED)
url = boto3.client("s3", config=my_config).generate_presigned_url(
    "get_object", ExpiresIn=0, Params={"Bucket": bucket_name, "Key": key}
)

...如here所述。

答案 4 :(得分:0)

您可以生成预先签名的 URL,然后修剪其查询参数。 这需要相关存储桶的“s3:PutObject”权限。

url = s3client.generate_presigned_url(ClientMethod = 'put_object',
                                      Params = { 'Bucket': bucket_name, 'Key': key })

# trim query params
url = url[0 : url.index('?')]