我需要在上传文件后直接检索公共对象URL,以便将其存储在数据库中。 这是我的上传代码:
s3 = boto3.resource('s3')
s3bucket.upload_file(filepath, objectname, ExtraArgs={'StorageClass': 'STANDARD_IA'})
我不是在寻找预签名 URL,只是需要一个始终可通过 https 公开访问的 URL。
感谢您的任何帮助。
我需要在上传文件后直接检索公共对象URL,以便将其存储在数据库中。 这是我的上传代码:
s3 = boto3.resource('s3')
s3bucket.upload_file(filepath, objectname, ExtraArgs={'StorageClass': 'STANDARD_IA'})
我不是在寻找预签名 URL,只是需要一个始终可通过 https 公开访问的 URL。
感谢您的任何帮助。
没有简单的方法,但是你可以从存储桶所在的区域(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)
自2010年以来,您可以使用基于虚拟主机的S3网址,即无需与特定区域的网址混淆:
url = f'https://{bucket}.s3.amazonaws.com/{key}'
带引号的键:
url = f'''https://{bucket}.s3.amazonaws.com/{urllib.parse.quote(key, safe="~()*!.'")}'''
此外,对于在2020年9月30日或之前创建的存储桶,将继续支持路径样式模型(区域特定URL)。在该日期之后创建的存储桶必须使用虚拟主机模型进行引用。
另请参阅此博客文章。
quote_plus
来替换quote
. - Peter Harrison将原始密钥连接起来在某些特殊字符的情况下(例如:'+'),会失败,您必须对它们进行引用:
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}
)
......如此处所述。
https://s3-us-east-1...
不可用,其他地区可以使用。为了获得相同的行为,您应该使用 https://s3.us-east-1...
(请注意点号而不是破折号)。
请参阅 https://docs.aws.amazon.com/general/latest/gr/s3.html。 - Martin Royurl = s3client.generate_presigned_url(ClientMethod = 'put_object',
Params = { 'Bucket': bucket_name, 'Key': key })
# trim query params
url = url[0 : url.index('?')]
仅是一条小注。 函数调用
location =
boto3.client('s3').get_bucket_location(Bucket=bucket_name['LocationConstraint']
如果存储桶位于“us-east-1”区域,则可能返回位置为None。因此,我会修改上面的答案并在该行下方添加一行:
if location == None: location = 'us-east-1'