Код Python может быть развернут в лямбда AWS, но не в локальном стеке
Я разработал проект python (v3.6), который развернут и фактически работает в безсердечной лямбде в моей рабочей платформе AWS. Этот проект использует следующие зависимости:
- awscli==1.16.10
- boto3==1.9.0
- botocore==1.12.0
- psycopg2==2.7.5
- SQLAlchemy==1.2.11
- SQLAlchemy-Utils==0.33.3
- jsonschema==2.6.0
Теперь я хочу использовать localstack для развертывания этого проекта в лямбда-выражении, которое я смогу вызвать, чтобы протестировать мой код вызова (а не код моего проекта, который действительно работает!)
Чтобы развернуть проект, сначала я устанавливаю зависимости и создаю zip-файл:
pip install -r requirements.txt --upgrade -t ./
chmod -R 755 .
zip -r lambda.zip .
Затем я использую команду (с работающим локальным стеком):
aws lambda --region eu-east-1 --endpoint localhost:4574 \
create-function --function-name mylambda \
--zip-file fileb://lambda.zip
Тем не менее, он возвращает ошибку из localstack:
....
localstack_1 | from functools32 import lru_cache
localstack_1 | ImportError: No module named functools32
....
localstack_1 | raise Exception('Unable to get handler function from lambda code.', e)
localstack_1 | Exception: ('Unable to get handler function from lambda code.', ImportError('No module named functools32',))
Модуль functools32 используется jsonschema и доступен только для python 2.7 или <=3.2. Я использую Python 3.6, поэтому я не могу установить его. Кроме того, у меня не было этой ошибки при развертывании того же lambda.zip в моей рабочей платформе AWS.
Я действительно не знаю, как решить эту проблему. Если у кого-то есть идея проверить, я буду очень благодарен.
С Уважением,
0 ответов
То, как вы это сделали, очень похоже на меня, кроме того, что при создании лямбда-функции я добавляю еще несколько флагов, которые определяют функцию-обработчик, время выполнения и т. Д., Так что я бы сказал, что ваша ошибка лежит там. При этом я могу успешно запускать лямбду на AWS и на Localstack, поэтому я так и делаю:
Сначала создайте Dockerfile, который установит требования
# Dockerfile FROM lambci/lambda:build-python3.7 ENV REQPATH /root/requirements.txt COPY ./requirements.txt /root/requirements.txt pip3 install -i https://pypi.douban.com/simple -r ${REQPATH} --target=/opt/python/lib/python3.7/site-packages/ RUN cd /opt && zip -r /root/lambda-layer.zip *
Теперь создайте изображение и получите
.zip
файл из контейнера:#!/bin/bash docker build -t lambda-layer:my_version ${NOCACHE} . id=$(docker create lambda-layer:my_version) docker cp $id:/root/lambda-layer.zip ~/lambda-layer.zip docker rm -v $id
Теперь на этом этапе, что
.zip
файл может быть тем, который нужно будет загрузить в AWS, так как я пишу лямбда-функции прямо на их веб-сайте, но для Localstack нам нужно сделать новый.zip
файл, содержащий то же содержимое, что и только что созданный, но добавленный в сценарий Python для лямбды.Напишите лямбда-скрипт, который в данном случае зависит от стороннего модуля;
requests
:# lambda.py import requests def handler(event, context): print("--- testing localstack lambda ---") print("event: ", event) print("context: ", context.__dict__) r = requests.get("http://192.168.xx.xx/path/") print("r: ", r) return {"foo": "bar"}
Сделать новый
.zip
файл с приведенным выше скриптом Python:# shell $ cp lambda-layer.zip lambda-layer-localstack.zip $ zip -ur lambda-layer-localstack.zip lambda.py # Check contents on zip file contain the python # dependencies and lambda function script $ unzip -l lambda-layer-localstack.zip Archive: lambda-layer-localstack.zip Length Date Time Name --------- ---------- ----- ---- 0 2019-02-02 15:37 python/ 261 2019-02-02 15:43 lambda.py --------- ------- 261 2 files
Теперь нам просто нужно создать эту лямбда-функцию в Localstack
$ awslocal --endpoint-url=http://192.168.xx.xx:4569 \ lambda create-function \ --function-name=function1 \ --runtime=python3.7 \ --role=r1 \ --handler=lambda.handler --zip-file fileb://lambda-layer-localstack.zip
И наконец, проверьте, что это работает
$ awslocal --endpoint-url=http://192.168.2.75:4569 \ lambda invoke --function-name function1 result1.log { "StatusCode": 200 } # On docker-compose logs (docker-compose logs -f) localstack_1 | --- testing localstack lambda --- localstack_1 | ('event: ', None) localstack_1 | ('context: ', {..}) localstack_1 | ('r: ', <Response [200]>)