Yas*_*r S 1 python-3.x localstack
我开发了一个 python (v3.6) 项目,该项目在我的AWS 生产平台的无服务器 lambda 中部署并实际工作。该项目使用以下依赖项:
- 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
Run Code Online (Sandbox Code Playgroud)
现在我想使用 localstack 在一个 lambda 中部署这个项目,我可以调用它来测试我的调用代码(不是我的项目实际工作的代码!)
要部署项目,首先我安装依赖项并创建一个 zip 文件:
pip install -r requirements.txt --upgrade -t ./
chmod -R 755 .
zip -r lambda.zip .
Run Code Online (Sandbox Code Playgroud)
然后,我使用命令(使用正在运行的 localstack):
aws lambda --region eu-east-1 --endpoint localhost:4574 \
create-function --function-name mylambda \
--zip-file fileb://lambda.zip
Run Code Online (Sandbox Code Playgroud)
但是,它从 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',))
Run Code Online (Sandbox Code Playgroud)
模块 functools32 由 jsonschema 使用,它仅适用于 python 2.7 或 <=3.2。我正在使用 python 3.6,所以我无法安装它。此外,当我在我的 AWS 生产平台中部署相同的 lambda.zip 时,我没有出现此错误。
我真的不知道如何解决这个问题。如果有人有想法要检查,我将非常感激。
问候,
你这样做的方式与我非常相似,除了在创建 lambda 函数时我附加了一些定义处理程序函数、运行时等的标志,所以我会说你的错误就在那里。话虽如此,我可以在 AWS 和 Localstack 上成功运行 lambda,所以我是这样实现的:
首先制作一个 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 *
Run Code Online (Sandbox Code Playgroud)现在,构建映像并将.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
Run Code Online (Sandbox Code Playgroud)现在,该.zip文件可以是需要上传到 AWS 的文件,因为我直接在他们的网站上编写 lambda 函数,但是对于 Localstack,我们需要创建一个新.zip文件,其中包含与一个刚刚制作,但为 lambda 添加了一个 python 脚本。
在这种情况下,编写一个依赖于某些第三方模块的 lambda 脚本;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"}
Run Code Online (Sandbox Code Playgroud).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
Run Code Online (Sandbox Code Playgroud)现在我们只需要在 Localstack 上创建那个 lambda 函数
$ 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
Run Code Online (Sandbox Code Playgroud)最后,测试它是否有效
$ 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]>)
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
2058 次 |
| 最近记录: |