我需要在上传文件后直接检索公共对象URL,这样才能将其存储在数据库中。 这是我的上传代码:
s3 = boto3.resource('s3')
s3bucket.upload_file(filepath, objectname, ExtraArgs={'StorageClass': 'STANDARD_IA'})
我不是在寻找预先签名的网址,只是可以通过https公开访问的网址。
任何帮助表示感谢。
答案 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('?')]