Как проверить, существует ли определенный файл в папке верхнего уровня в s3, используя lambda, boto3 и python 2.7 - PullRequest
0 голосов
/ 16 октября 2018

Этот вопрос состоит из двух частей, я думаю, но я объясню: Сценарий:

У меня есть лямбда-функция, которая создает папку в S3 для пользователя, если у него ее нет, и тогда она будетв конечном итоге будет заполнен mp3-файлами.Для моих тестовых случаев я должен обработать, если файл существует.Для этого я пытаюсь использовать это:

s3client = boto3.client('s3')
bucket_name = os.environ['BUCKET_NAME']
prefix = email + "/"
resp = s3client.list_objects(Bucket=bucket_name, Prefix=prefix, Delimiter="/")
print resp 
print resp.get(email + "/" + postId + ".mp3")

Я всегда получаю NoneType, потому что он не существует, но для целей тестирования у меня уже есть все, и я просто хочу, чтобы пример успеха прошел,так что он существует, но я не получаю информацию должным образом.

Ответ, полученный при печати переменной resp:

{u'Name': 'listen-n-save-mp3', 'ResponseMetadata': {'HTTPStatusCode': 200, 'RetryAttempts': 0, 'HostId': 'QcxxxfYu1GunfZ2dXMUo=', 'RequestId': '16BCFFD288F16D74', 'HTTPHeaders': {'x-amz-bucket-region': 'us-east-1', 'x-amz-id-2': 'QRxZVUnWzcxxx22K5RoFKgxKfYu1GunfZ2dXMUo=', 'server': 'AmazonS3', 'transfer-encoding': 'chunked', 'x-amz-request-id': '16BCFFD288F16D74', 'date': 'Tue, 16 Oct 2018 19:23:06 GMT', 'content-type': 'application/xml'}}, u'Delimiter': u'/', u'MaxKeys': 1000, u'Prefix': 'philips%40exmaple.com/', u'Marker': u'', u'EncodingType': 'url', u'IsTruncated': False, u'Contents': [{u'LastModified': datetime.datetime(2018, 10, 16, 19, 22, 6, tzinfo=tzlocal()), u'ETag': '"xxxx"', u'StorageClass': 'STANDARD', u'Key': u'philips@exmaple.com/', u'Owner': {u'DisplayName': 'listennsave', u'ID': 'xxxx'}, u'Size': 0}, {u'LastModified': datetime.datetime(2018, 10, 16, 18, 57, 43, tzinfo=tzlocal()), u'ETag': '"xxxx"', u'StorageClass': 'STANDARD', u'Key': u'philips@exmaple.com/supImanId.mp3', u'Owner': {u'DisplayName': 'listennsave', u'ID': 'xxx'}, u'Size': 36942}]}

Ответ очень длинный и отформатированныйк одной строке, к сожалению, автоматически, но внутри папки есть ключ с именем u'Key': u'philips@exmaple.com/supImanId.mp3', который вы можете видеть в конце этой строки.Мой первый вопрос: как мне правильно получить доступ к этому ключу с помощью метода get?

Мой второй вопрос: когда я знаю, что правильно получаю ключ и он возвращает NoneType (имеется в виду, что он еще не создан), как я могу использовать его как условный оператор, который позволяет функции продолжать?

Спасибо за ваше время.

================================================================

Редактировать: Это то, что у меня есть сейчас

s3client = boto3.client('s3')
bucket_name = os.environ['BUCKET_NAME']
prefix = email + "/"
print bucket_name
resp = s3client.list_objects(Bucket=bucket_name, Prefix=prefix, Delimiter="/")

this_item =  [item for item in resp['Contents'] if item.get('Key')==email + "/" + postId + ".mp3" ]
try:
    this_item[0]['Key']
except IndexError:
    pass
continue

Проблема в том, что если мне ничего не возвращают, я хочу, чтобы эта функция работала правильно.Я пытался с этим синтаксисом, но я получаю сообщение об ошибке зацикливания

Syntax error in module 'lambda_function': 'continue' not properly in loop (lambda_function.py, line 80)

Итак, мне нужен цикл, я полагаю?Где и как мне начать цикл с моей текущей настройкой?Кажется простым, но я очень плохо знаком с Python, так что это будет полезно!

1 Ответ

0 голосов
/ 17 октября 2018

Ответ от list_objects() следует определенной структуре, которая определяет набор метаданных о запросе вместе с содержимым результата.Подробнее о том, что находится в файле ответов и как оно структурировано, можно прочитать в документации boto3 .

Объект ответа - это просто словарь.Значение Key вложено в Contents, поэтому для доступа к Key в объекте ответа вы можете использовать:

k = resp['Contents']['Key']

Если по запросу возвращается несколько ключей, вы можете просто зациклитьчерез объекты Contents и создайте список всех возвращаемых ключей следующим образом:

all_keys = [k["Key"] for k in resp["Contents"]
...