Как получить область сегмента и передать ее клиенту o создать предопределенные URL-адреса aws s3 - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть этот код для генерации предварительно назначенного URL-адреса для недавнего объекта, совпадающего со строкой.

Проблема заключается в том, как я могу передать правильную область клиенту s3 при создании URL-адреса, этот код имеет бесполезно, если он не генерирует правильный 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")))```

Ответы [ 4 ]

3 голосов
/ 26 апреля 2020

Расширяя ответ @ wpp, ваш код будет выглядеть примерно так:

def create_presigned_url(bucket_name, object_name, expiration=3600):

    # Get region for bucket
    s3_client = boto3.client('s3')
    response = s3_client.get_bucket_location(Bucket=bucket_name)

    # Generate a presigned URL for the S3 object
    s3_client = boto3.client('s3', region_name=response['LocationConstraint'])
    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
2 голосов
/ 25 апреля 2020

Чтобы получить область сегмента, используйте get_bucket_location() метод клиента S3.

От вас может потребоваться создать сеанс boto3 в этом регионе, а затем клиент из этого сеанса.

1 голос
/ 26 апреля 2020

Оптимизация ответа Джона.

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")
1 голос
/ 25 апреля 2020

Из boto3 используйте этот класс (см. Пример внизу)

s3.client class

import boto3
client = boto3.client('s3')

Доступны следующие методы:

get_bucket_location(**kwargs)

Возвращает регион, в котором находится контейнер. Вы задаете Регион ведра с использованием параметра запроса LocationConstraint в запросе CreateBucket. Для получения дополнительной информации см. CreateBucket .

** Обратите внимание, что для использования этой реализации операции вы должны быть владельцем корзины.

Следующие операции относятся к GetBucketLocation (См. Документацию API AWS ):

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'
}

Структура ответа

(dict) - LocationConstraint (string) - Указывает регион, в котором находится сегмент. Список всех поддерживаемых Amazon S3 ограничений местоположения по регионам см. В разделе «Регионы и конечные точки».

Примеры

В следующем примере возвращается местоположение сегмента.

import boto3

client = boto3.client('s3')

response = client.get_bucket_location(
    Bucket='examplebucket',
)

print(response)
Expected Output:

{
    'LocationConstraint': 'us-west-2',
    'ResponseMetadata': {
        '...': '...',
    },
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...