Как изменить / заменить изображение S3 с помощью Python и библиотеки Chalice?

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

@app.on_s3_event(bucket=settings.BUCKET_NAME, events=['s3:ObjectCreated:*'])
def compress(event):           
    # download the resource
    s3.Bucket(settings.BUCKET_NAME).download_file(key, local_file_path)

    # compress the image
    ...

    # rename the file, if necessary (change extension, etc.)
    ...

    # upload the new image
    s3.Object(settings.BUCKET_NAME, output_path).put(Body=open(compressed_path, 'rb'))    

    # remove original image
    s3.Object(settings.BUCKET_NAME, event.key).delete()

Так что, если я загружу изображение с именем sample.png на S3, он сжимается и переименовывается, скажем, sample.jpg; а также sample.png будет удален позже.

Проблема, однако, заключается в том, что решение приведет к бесконечной рекурсии. Причина заключается в том, что загрузка сжатого изображения снова вызовет лямбда-функцию, вызывая тем самым загрузку снова, тем самым сжимая уже сжатое изображение, тем самым загружая его снова. До бесконечности.

Мой друг предложил два возможных решения: кэшировать имя сжатого изображения, сохраняя его где-то в отдельном файле корзины S3, и предотвращать загрузку кэшированных имен файлов более одного раза; и изменить exif/metada сжатого изображения так, чтобы лямбда могла сказать, какие файлы уже были сжаты, указывая, что функция не должна выполняться, что предотвратит повторное сжатие.

Первая идея склонна к проблемам, которые могут возникнуть, когда несколько файлов загружаются на сервер одновременно, по крайней мере теоретически. Вторая идея может потребовать сторонней библиотеки, такой как piexif, но это та, которую я сейчас рассматриваю.

У вас есть лучший способ решения этой проблемы? Или я вообще занимаюсь сжатием (кроме рекурсивной загрузки и выгрузки) прямо с самого начала? Я имею в виду, возможно, я могу сжать изображения S3, не выполняя процедуру загрузки-сжатия-загрузки-удаления.

1 ответ

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

Предположим, изображения загружаются в формате .jpeg, а вы сжимаете и конвертируете их в .png. Теперь, поскольку недавно обновленное изображение находится в формате .png, ваша лямбда-функция не будет запускаться.

Другие вопросы по тегам