как скачать файл S3 в безсерверной лямбде (Python) - PullRequest
0 голосов
/ 21 января 2019

Я создал лямбду в Python (используя Serverless), которая будет вызываться сообщением SQS.

handler.py

s3 = boto3.resource('s3')

def process(event, context):
    response = None
    # for record in event['Records']:
    record = event['Records'][0]
    message = dict()
    try:
        message = json.loads(record['body'])

        s3.meta.client.download_file(const.bucket_name, 'class/raw/photo/' + message['photo_name'], const.raw_filepath + message['photo_name'])    

        ...

        response = {
            "statusCode": 200,
            "body": json.dumps(event)
        }

    except Exception as ex:
        error_msg = 'JOB_MSG: {}, EXCEPTION: {}'.format(message, ex)
        logging.error(error_msg)

        response = {
                "statusCode": 500,
                "body": json.dumps(ex)
            }

    return response

const.py

bucket_name = 'test'
raw_filepath = '/var/task/raw/'

Я создал папку «raw», того же уровня, что и файл handler.py, а затем развернул серверную лямбду.

Я получил сообщение об ошибке (из CloudWatch) при запуске лямбды.

No such file or directory: u'/var/task/raw/Student001.JPG.94BBBAce'

Как я понимаю, папка lambda недоступна или папка не может быть создана в lambda.

На всякий случай я разделяю цели лямбды:

  • скачать файл S3 raw
  • изменить размер файла и загрузить новый файл в другую корзину S3

Любое предложение приветствуется.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2019

В одном из моих проектов я конвертировал файлы webp в jpg. Я могу обратиться к следующей ссылке на GitHub, чтобы получить некоторое понимание:

https://github.com/adjr2/webp-to-jpg/blob/master/codes.py

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

Надеюсь, это поможет. Ура!

0 голосов
/ 21 января 2019

Если вам нужно загрузить объект на диск, вы можете использовать tempfile и download_fileobj для его сохранения:

import tempfile

with tempfile.TemporaryFile() as f:
    s3.meta.client.download_fileobj(const.bucket_name, 
                                   'class/raw/photo/' + message['photo_name'],
                                    f)
    f.seek(0)
    # continue processing f

Обратите внимание, что существует ограничение 512 МБ о размере временных файлов в Lambda.

Я бы сказал, что еще лучший способ - это обработать все это в памяти.Вместо tempfile вы можете использовать io очень похожим образом:

import io

data_stream = io.BytesIO()
s3.meta.client.download_fileobj(const.bucket_name, 
                               'class/raw/photo/' + message['photo_name'],
                                data_stream)
data_stream.seek(0)

Таким образом, данные не нужно записывать на диск, что а) быстрее и б)Вы можете обрабатывать большие файлы, в основном, пока не достигнете предела памяти Lambda 3008 МБ или памяти.

...