Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何获取bucket区域并将其传递给客户端以生成预签名的URL_Python_Python 3.x_Amazon Web Services_Amazon S3_Boto3 - Fatal编程技术网

Python 如何获取bucket区域并将其传递给客户端以生成预签名的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="

我有以下代码来为最近匹配字符串的对象生成预签名的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="", 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会话,然后执行client
s3\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生成,所以您需要对此进行测试。如何测试