我想设置一个我在AWS Lambda上编写的Python函数,这个函数依赖于我已经在conda environment收集的一堆Python库。
要在Lambda上进行设置,我应该将此环境压缩,但Lambda docs仅提供有关如何使用pip / VirtualEnv执行此操作的说明。有没有人有这方面的经验?
答案 0 :(得分:8)
您应该将serverless framework与serverless-python-requirements plugin结合使用。您只需要一个requirements.txt
,插件会自动将您的代码和依赖项打包到一个zip文件中,将所有内容上传到s3并部署您的函数。额外:因为它可以做到这个停靠,它也能够帮助你处理需要二进制依赖的包。
请查看here (https://serverless.com/blog/serverless-python-packaging/)了解操作方法。
根据经验,我强烈建议你研究一下。用于部署的每一点手工劳动都可以阻止您开发逻辑。
编辑2017-12-17:
您的评论有意义@eelco-hoogendoorn。
但是,在我看来,conda环境只是一个封装的地方,其中包含一堆python包。那么,如果您将所有这些依赖项(来自您的conda env)放入requirements.txt
(并使用无服务器+插件)来解决您的问题,不是吗?
恕我直言,它基本上与将您在env中安装的所有软件包压缩到部署包中相同。话虽这么说,这是一个片段,基本上是这样的:
conda env export --name Name_of_your_Conda_env | yq -r '.dependencies[] | .. | select(type == "string")' | sed -E "s/(^[^=]*)(=+)([0-9.]+)(=.*|$)/\1==\3/" > requirements.txt
不幸的是conda env export
仅以yaml格式导出环境。 --json
标志现在不起作用,但应该在下一个版本中修复。这就是我必须使用 yq 而不是 jq 的原因。您可以使用yq
安装pip install yq
。它只是jq
的包装器,允许它也可以使用yaml文件。
保持心情
Lambda部署代码的大小只能为50MB。你的环境不应该太大。
我没有尝试使用serverless
+ serverless-python-packaging
和requirements.txt
部署一个lambda,并且我不知道它是否会起作用。
答案 1 :(得分:2)
我想你可以进入你的anaconda2/envs/
或anaconda3/envs/
目录并复制/压缩你要上传的env目录。 Conda只是一个增强版的virtualenv,加上一个不同的&有点可选的包管理器。我认为没问题的一个重要原因是conda环境默认情况下将所有依赖项封装在其特定的.../anaconda[2|3]/envs/$VIRTUAL_ENV_DIR/
目录中。
使用普通的virtualenv表达式可以让你获得更多的自由,就像洞穴人比现代人拥有更多自由一样。我个人比较喜欢汽车。使用virtualenv,你基本上可以得到一个半空的$PYTHON_PATH
变量,你可以用你想要的任何东西填充,而不是Conda吐出的更强大,预先填充的env。以下是一个很好的参考表:https://conda.io/docs/commands.html#conda-vs-pip-vs-virtualenv-commands
~$ /path/to/$VIRTUAL_ENV_ROOT_DIR/bin/activate
转换为~$ source activate $VIRTUAL_ENV_NAME
假设你想以老式方式制作virtualenv
。你要选择一个目录(我们称之为$VIRTUAL_ENV_ROOT_DIR
),&名称(我们称之为$VIRTUAL_ENV_NAME
。)此时您将输入:
~$ cd $VIRTUAL_ENV_ROOT_DIR && virtualenv $VIRTUAL_ENV_NAME
然后 python创建一个自己的解释器库的副本(我认为还有pip和setuptools)&在此克隆的activate
目录中放置一个名为bin/
的可执行文件。 $VIRTUAL_ENV_ROOT_DIR/bin/activate
脚本的工作原理是更改当前的$PYTHONPATH
环境变量,该变量确定在shell中键入~$ python
时调用的python解释器,&还包含解释器在被告知import
时会看到的所有模块的目录列表。这是您在人员代码中看到#!/usr/bin/env python
而不是/usr/bin/python
的主要原因。
答案 2 :(得分:2)
我使用conda
的主要原因是我不能自己编译不同的二进制包(如numpy
,matplotlib
,pyqt
等)或编译它们不太常见。如果您确实需要为python
的特定版本(例如uwsgi
)自行编译某些内容,则应使用与gcc
版本相同的python
版本编译二进制文件。编译conda
环境 - 很可能与您的操作系统使用的gcc
不同,因为conda
现在正在使用应该是gcc
的最新版本与conda install gxx_linux-64
一起安装。
这引出了两种情况:
所有依赖项都在纯python中,您实际上可以使用pip freeze
保存它们列表的列表,并按照virtualenv
的说明捆绑它们。
您有一些二进制扩展名。在这种情况下,来自conda环境的二进制文件将无法与AWS lambda使用的python一起使用。不幸的是,您需要访问描述执行环境的page(AMI:amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2),设置环境,为特定版本的内置版本构建二进制文件在python中的一个单独的目录(以及纯python包),然后将它们捆绑成一个zip-archive。
这是对您的问题的一般答案,但主要的想法是您不能重复使用二进制包,只能列出它们的列表。
答案 3 :(得分:1)
在https://github.com/dazza-codes/aws-lambda-layer-packing中,pip wheel似乎适用于许多软件包(纯pip安装)。很难将许多软件包捆绑到一个紧凑的AWS Lambda层中,因为pip wheel不使用共享库,并且会有点肿,但它们可以工作。根据github中的一些讨论,conda vs. pip挑战并不容易: