Эффективно найти все .zip файлы в корзине S3 - PullRequest
0 голосов
/ 31 января 2020

У меня есть куча S3-контейнеров со старыми файлами и архивами (в формате .zip). Я хочу эффективно запросить корзину и получить список всех файлов, которые упакованы в архив и имеют размер, скажем, 200 МБ, а затем удалить их.

Итак, я написал некоторый код. Это делает работу, но это медленно. Чем больше файлов на S3, тем больше вызовов API, тем дольше время ожидания. Для корзины с 70+ файлами требуется приблизительно 50 секунд, чтобы в этом случае записать 3 zip-файла.

#!/usr/bin/env python3.6
import boto3
from botocore.exceptions import ClientError


def find_all_zips(bucket: str) -> iter:
    print(f"Looking for .zip files on S3: {bucket} ...")
    b = boto3.resource("s3").Bucket(bucket)
    return (obj.key for obj in b.objects.all()
            if get_info(bucket=bucket, key=obj.key) is not None)


def get_info(bucket: str, key: str) -> str:
    s3 = boto3.client('s3')
    try:
        response = s3.head_object(Bucket=bucket, Key=key)
        has_size = response['ContentLength'] >= 209715200 # ~= 200MB in bytes
        if len(response['ContentType']) == 0:
            is_zip = False
        else:
            is_zip = response['ContentType'].split("/")[1] == 'zip'

        if has_size and is_zip:
            return key
    except ClientError as error:
        raise Exception(f"Failed to fetch file info for {key}: {error}")


if __name__ == "__main__":
    print(list(find_all_zips(bucket='MYBUCKET')))

Вывод, который я получаю, - это то, что я ожидаю:

Looking for .zip files on S3: MYBUCKET ...
['avocado-prices.zip', 'notepad.zip', 'spacerace.zip']

Вопрос: Есть ли способ ускорить эту вещь? Или мне следует развернуть базу данных, в которой хранятся вкладки моих файлов S3 и их типов?

1 Ответ

1 голос
/ 01 февраля 2020

Если вы хотите использовать имя файла для идентификации Zip-файла, вам не нужен дополнительный вызов head_object():

import boto3

s3_resource = boto3.resource('s3')
bucket = s3_resource.Bucket('my_bucket')

max_size = 2 * 1024 * 1024

print(list(object.key for object in bucket.objects.all()
            if object.size >= max_size and object.key.endswith('.zip')))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...