AWS Lambda的conda环境

时间:2016-09-28 14:21:53

标签: python amazon-web-services aws-lambda conda

我想设置一个我在AWS Lambda上编写的Python函数,这个函数依赖于我已经在conda environment收集的一堆Python库。

要在Lambda上进行设置,我应该将此环境压缩,但Lambda docs仅提供有关如何使用pip / VirtualEnv执行此操作的说明。有没有人有这方面的经验?

4 个答案:

答案 0 :(得分:8)

您应该将serverless frameworkserverless-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-packagingrequirements.txt部署一个lambda,并且我不知道它是否会起作用。

答案 1 :(得分:2)

我想不出为什么拉扯你的conda环境不起作用的充分理由。

我想你可以进入你的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

Conda将命令~$ /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的主要原因是我不能自己编译不同的二进制包(如numpymatplotlibpyqt等)或编译它们不太常见。如果您确实需要为python的特定版本(例如uwsgi)自行编译某些内容,则应使用与gcc版本相同的python版本编译二进制文件。编译conda环境 - 很可能与您的操作系统使用的gcc不同,因为conda现在正在使用应该是gcc的最新版本与conda install gxx_linux-64一起安装。

这引出了两种情况:

  1. 所有依赖项都在纯python中,您实际上可以使用pip freeze保存它们列表的列表,并按照virtualenv的说明捆绑它们。

  2. 您有一些二进制扩展名。在这种情况下,来自conda环境的二进制文件将无法与AWS lambda使用的python一起使用。不幸的是,您需要访问描述执行环境的page(AMI:amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2),设置环境,为特定版本的内置版本构建二进制文件在python中的一个单独的目录(以及纯python包),然后将它们捆绑成一个zip-archive。

  3. 这是对您的问题的一般答案,但主要的想法是您不能重复使用二进制包,只能列出它们的列表。

答案 3 :(得分:1)

https://github.com/dazza-codes/aws-lambda-layer-packing中,pip wheel似乎适用于许多软件包(纯pip安装)。很难将许多软件包捆绑到一个紧凑的AWS Lambda层中,因为pip wheel不使用共享库,并且会有点肿,但它们可以工作。根据github中的一些讨论,conda vs. pip挑战并不容易: