Почему время ожидания AWS Lambda истекает при передаче функции декоратору?

Я работаю над функцией python AWS Lambda, которая использует pydantic для проверки ввода. Недавно я обнаружил, что время ожидания Lambda истекло (с тайм-аутом 15 секунд) при выполнении следующего кода:

def _stringify(v):
    return str(v)

class SomeModel(BaseModel):
    a: int
    _stringify = validator("a", allow_reuse=True)(_stringify)

SomeModel(a=12)

Я определил, что проблема возникает при вызове _stringify = validator("a", allow_reuse=True)(_stringify), который передает функцию _stringify декоратору валидатора. Это полностью функционально в локальной среде, но не в AWS Lambda. Следующее альтернативное определение SomeModel также работает в среде AWS Lambda.

class SomeModel(BaseModel):
    a: int

    @validator("a")
    def stringify(cls, v):
        return str(v)

Есть ли у кого-нибудь, кто лучше разбирается в AWS Lambda, какие-либо идеи относительно того, почему _stringify = validator("a", allow_reuse=True)(_stringify) приводит к тайм-ауту, и можете ли вы предложить какие-либо возможные исправления?

(Примечание: альтернативное определение SomeModel нежелательно, поскольку оно нарушает принципы DRY, поскольку мы хотим использовать _stringify в нескольких моделях.)

Код не вызывает исключений при выполнении как локально, так и в среде Lambda.

Среда:
AWS Lambda
python 3.8 — пользовательская сборка среды выполнения с помощью Docker. Лямбда-слои, поддерживающие:

  • пидантик — v1.6.1 (питон 3.8)

person abercon    schedule 17.08.2020    source источник
comment
Сколько времени это занимает, когда вы запускаете локально? Есть ли исключения?   -  person Parsifal    schedule 17.08.2020
comment
Рабочая версия эквивалентна написанию stringify = validator("a")(stringify) после простого определения функции. Нерабочая версия - это в основном только часть после знака равенства - вы на самом деле ничего не определяете, SomeModel никоим образом не зависит от строки кода.   -  person jasonharper    schedule 17.08.2020
comment
Локально запуск @Parsifal занимает 1,4 микросекунды.   -  person abercon    schedule 17.08.2020
comment
Я попробовал ваше предложение @jasonharper, но это не решило проблему. Хороший улов, однако :).   -  person abercon    schedule 17.08.2020
comment
Я отредактировал код, чтобы исправить ошибку, замеченную @jasonharper.   -  person abercon    schedule 17.08.2020


Ответы (1)


Среда: питон 3.8

AWS Lambda не поддерживает Python 3.8, если вы не используете собственную настраиваемую среду выполнения (https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html).

Вам необходимо сделать следующие шаги:

  1. Проверьте, работает ли ваш код без проблем под Python 3.7.
  2. Проверьте настройки вашей Lambda и убедитесь, что она настроена на использование Python 3.7.
  3. Подготовьте zip-файл со всеми вашими сторонними зависимостями (pydantic и т. д.) и загрузите его на веб-страницу конфигурации вашего AWS Lambda или используйте его в своих скриптах в процессе развертывания вашего Lambda: https://docs.aws.amazon.com/lambda/latest/dg/python-package.html . Не забудьте использовать Python3.7 и соответствующий дистрибутив Linux для этого шага. Лучше использовать CentOS (или соответствующий пакет Windows Subsystem for Linux (WSL)). Однако Ubuntu 18.04 (и соответствующий пакет WSL) большую часть времени работает правильно. Загрузите соответствующие файлы .whl, совместимые с Linux, с сайта pypi.org, если вы столкнулись с проблемой с каким-либо сторонним пакетом Python, и добавьте этот файл .whl в сгенерированный файл .zip со сторонними зависимостями.

Без нашего шага №3 вы не сможете использовать сторонние библиотеки

person KromviellBlack    schedule 17.08.2020
comment
Всем привет! Мы работаем с пользовательской средой выполнения, созданной с использованием докера для поддержки python 3.8 и других зависимостей. Я обновлю пост, чтобы сделать это более явным. - person abercon; 18.08.2020