Python 如何获取bucket区域并将其传递给客户端以生成预签名的URL
我有以下代码来为最近匹配字符串的对象生成预签名的URL 问题是如何在生成URL时将正确的区域传递给s3客户机,如果没有生成正确的URL,则此代码没有任何用处Python 如何获取bucket区域并将其传递给客户端以生成预签名的URL,python,python-3.x,amazon-web-services,amazon-s3,boto3,Python,Python 3.x,Amazon Web Services,Amazon S3,Boto3,我有以下代码来为最近匹配字符串的对象生成预签名的URL 问题是如何在生成URL时将正确的区域传递给s3客户机,如果没有生成正确的URL,则此代码没有任何用处 #! /usr/bin/python #This script generates S3 object pre-signed URL import logging import boto3 from botocore.exceptions import ClientError def keys(bucket_name, prefix="
#! /usr/bin/python
#This script generates S3 object pre-signed URL
import logging
import boto3
from botocore.exceptions import ClientError
def keys(bucket_name, prefix="", delimiter="/"):
"""Generate a key listings
:param bucket_name: string
:param prefix: string
:param delimiter: string
"""
for page in (
boto3.client("s3")
.get_paginator("list_objects_v2")
.paginate(
Bucket=bucket_name,
Prefix=prefix[len(delimiter) :] if prefix.startswith(delimiter) else prefix,
**{"StartAfter": prefix} if prefix.endswith(delimiter) else {}
)
):
for content in page.get("Contents", ()):
yield content["Key"]
def latest(bucket_name, prefix):
"""Generate a latest logfile
:param bucket_name: string
:param prefix: string
:return: Object keys
"""
return(max(i for i in keys(bucket_name) if prefix in i))
def create_presigned_url(bucket_name, object_name, expiration=3600):
"""Generate a presigned URL to share an S3 object
:param bucket_name: string
:param object_name: string
:param expiration: Time in seconds for the presigned URL to remain valid
:return: Presigned URL as string. If error, returns None.
"""
# Generate a presigned URL for the S3 object
s3_client = boto3.client('s3')
try:
response = s3_client.generate_presigned_url('get_object',
Params={'Bucket': bucket_name,
'Key': object_name},
ExpiresIn=expiration)
except ClientError as e:
logging.error(e)
return None
# The response contains the presigned URL
return response
print(create_presigned_url("database-backup", latest("database-backup", "my-backup")))```
要获取bucket的区域,请使用S3客户端的
get\u bucket\u location()
方法
您可能需要在此区域中创建boto3会话,然后从该会话中创建客户端。要获取bucket的区域,请使用S3客户端的
get\u bucket\u location()
方法
您可能需要在此区域中创建boto3会话,然后从该会话中创建客户端。从“使用此类”(请参阅底部的示例)
以下是可用的方法:
获取桶位置(**kwargs)
返回存储桶所在的区域。您可以使用CreateBucket
请求中的LocationConstraint
request参数设置bucket的区域。有关详细信息,请参阅
**请注意,要使用此操作实现,您必须是bucket所有者
以下操作与GetBucketLocation
相关(请参阅):
GetObject
CreateBucket
请求语法
response = client.get_bucket_location(
Bucket='string'
)
Parameters
Bucket (string) --
[REQUIRED]
要获取其位置的存储桶的名称
Return type
dict
Returns
Response Syntax
{
'LocationConstraint': 'EU'|'eu-west-1'|'us-west-1'|'us-west-2'|'ap-south-1'|'ap-southeast-1'|'ap-southeast-2'|'ap-northeast-1'|'sa-east-1'|'cn-north-1'|'eu-central-1'
}
import boto3
client = boto3.client('s3')
response = client.get_bucket_location(
Bucket='examplebucket',
)
print(response)
Expected Output:
{
'LocationConstraint': 'us-west-2',
'ResponseMetadata': {
'...': '...',
},
}
响应结构
(dict)--
位置约束(字符串)--
指定存储桶所在的区域。有关按区域列出的所有AmazonS3支持的位置约束的列表,请参阅区域和端点
示例
下面的示例返回bucket location
Return type
dict
Returns
Response Syntax
{
'LocationConstraint': 'EU'|'eu-west-1'|'us-west-1'|'us-west-2'|'ap-south-1'|'ap-southeast-1'|'ap-southeast-2'|'ap-northeast-1'|'sa-east-1'|'cn-north-1'|'eu-central-1'
}
import boto3
client = boto3.client('s3')
response = client.get_bucket_location(
Bucket='examplebucket',
)
print(response)
Expected Output:
{
'LocationConstraint': 'us-west-2',
'ResponseMetadata': {
'...': '...',
},
}
使用此类(请参阅底部的示例)
以下是可用的方法:
获取桶位置(**kwargs)
返回存储桶所在的区域。您可以使用CreateBucket
请求中的LocationConstraint
request参数设置bucket的区域。有关详细信息,请参阅
**请注意,要使用此操作实现,您必须是bucket所有者
以下操作与GetBucketLocation
相关(请参阅):
GetObject
CreateBucket
请求语法
response = client.get_bucket_location(
Bucket='string'
)
Parameters
Bucket (string) --
[REQUIRED]
要获取其位置的存储桶的名称
Return type
dict
Returns
Response Syntax
{
'LocationConstraint': 'EU'|'eu-west-1'|'us-west-1'|'us-west-2'|'ap-south-1'|'ap-southeast-1'|'ap-southeast-2'|'ap-northeast-1'|'sa-east-1'|'cn-north-1'|'eu-central-1'
}
import boto3
client = boto3.client('s3')
response = client.get_bucket_location(
Bucket='examplebucket',
)
print(response)
Expected Output:
{
'LocationConstraint': 'us-west-2',
'ResponseMetadata': {
'...': '...',
},
}
响应结构
(dict)--
位置约束(字符串)--
指定存储桶所在的区域。有关按区域列出的所有AmazonS3支持的位置约束的列表,请参阅区域和端点
示例
下面的示例返回bucket location
Return type
dict
Returns
Response Syntax
{
'LocationConstraint': 'EU'|'eu-west-1'|'us-west-1'|'us-west-2'|'ap-south-1'|'ap-southeast-1'|'ap-southeast-2'|'ap-northeast-1'|'sa-east-1'|'cn-north-1'|'eu-central-1'
}
import boto3
client = boto3.client('s3')
response = client.get_bucket_location(
Bucket='examplebucket',
)
print(response)
Expected Output:
{
'LocationConstraint': 'us-west-2',
'ResponseMetadata': {
'...': '...',
},
}
扩展@wpp的答案,您的代码将如下所示:
def create_presigned_url(bucket_name,object_name,expiration=3600):
#获取桶的区域
s3\u client=boto3.client('s3'))
response=s3\u client.get\u bucket\u location(bucket=bucket\u name)
#为S3对象生成预签名的URL
s3_client=boto3.client('s3',region_name=response['LocationConstraint']))
尝试:
response=s3\u client.generate\u presigned\u url('get\u object',
Params={'Bucket':Bucket_名称,
“键”:对象名称},
ExpiresIn=到期日)
除ClientError作为e外:
logging.error(e)
一无所获
扩展@wpp的答案,您的代码将如下所示:
def create_presigned_url(bucket_name,object_name,expiration=3600):
#获取桶的区域
s3\u client=boto3.client('s3'))
response=s3\u client.get\u bucket\u location(bucket=bucket\u name)
#为S3对象生成预签名的URL
s3_client=boto3.client('s3',region_name=response['LocationConstraint']))
尝试:
response=s3\u client.generate\u presigned\u url('get\u object',
Params={'Bucket':Bucket_名称,
“键”:对象名称},
ExpiresIn=到期日)
除ClientError作为e外:
logging.error(e)
一无所获
优化@john的答案
def create_presigned_url(bucket_name, object_name, expiration=3600):
"""Generate a presigned URL to share an S3 object
:param bucket_name: string
:param object_name: string
:param expiration: Time in seconds for the presigned URL to remain valid
:return: Presigned URL as string. If error, returns None.
"""
# Generate a presigned URL for the S3 object
s3_client = boto3.session.Session(
region_name=boto3.client('s3').get_bucket_location(Bucket=bucket_name)["LocationConstraint"]
).client("s3")
优化@john的答案
def create_presigned_url(bucket_name, object_name, expiration=3600):
"""Generate a presigned URL to share an S3 object
:param bucket_name: string
:param object_name: string
:param expiration: Time in seconds for the presigned URL to remain valid
:return: Presigned URL as string. If error, returns None.
"""
# Generate a presigned URL for the S3 object
s3_client = boto3.session.Session(
region_name=boto3.client('s3').get_bucket_location(Bucket=bucket_name)["LocationConstraint"]
).client("s3")
我指的是一个链接,得到了这个,
def get_location(client,bucket_name):response=client.get_bucket_location(bucket=bucket_name)返回response['LocationConstraint']
这将如何适应我的代码,你能帮助我在创建客户端之前获取位置吗,然后通过执行session=boto3.session(region\u name=location)
创建boto3会话,然后执行clients3\u client=session.client('s3')
。但老实说,我不记得将客户端设为区域是否会影响URL生成,所以您需要对此进行测试。此位置boto3.Session(region\u name=location)
将如何进行?此工作是否有效?``Session=boto3.Session.Session(region\u name=get\u bucket\u location(bucket\u name))``给我错误,session=bot3.session.session(region\u name=get\u bucket\u location(bucket\u name))name错误:name'get\u bucket\u location'未定义
这将如何适合我的代码,您能帮助您在创建客户端之前获取位置,然后通过执行session=boto3.session(region\u name=location)
创建boto3会话,然后执行客户端s3\u client=session.client('s3')
。但说实话,我不记得将客户端区域化是否会影响URL生成,所以您需要对此进行测试。如何测试