在AWS Lambda的子目录中打包Python依赖项

时间:2018-04-15 08:23:59

标签: python pip aws-lambda serverless-framework python-packaging

我遇到了article on serverlesscode.com关于为AWS Lambda构建Python 3应用程序的问题,建议使用pip(或pip3)在/ vendored子目录中安装依赖项。我喜欢这个想法,因为它保持文件结构清洁,但我遇到了一些问题。

我使用无服务器框架,我的模块以正常方式导入我的代码中,例如from pynamodb.models import Model

我已经使用命令pip install -t vendored/ -r requirements.txt在子目录中安装我的各种依赖项(每个requirements.txt),这似乎按预期工作 - 我可以看到子目录中安装的所有模块。

但是,当调用该函数时,我收到错误Unable to import module 'handler': No module named 'pynamodb'(其中pynamodb是已安装的模块之一)。

我可以通过将我的pip安装更改为项目根目录来解决此错误,即不在/ vendored文件夹(pip install -t ./ -r requirements.txt)中。这将安装完全相同的文件。

必须有一个我错过的配置指向子文件夹,但谷歌搜索还没有显示我是否需要以不同的方式导入我的模块,或者是否有其他全局配置我需要改变。

总结一下:如何使用Pip在项目的子文件夹中安装我的依赖项?

编辑 :注意tkwargs'关于使用无服务器插件进行打包的好建议,例如,如果没有venv,如何理解这一点仍然是很好的。主要目的不是使包装更容易(它与pip一样简单),而是通过避免根目录中的其他文件夹来保持我的文件结构更清晰。

1 个答案:

答案 0 :(得分:4)

我看到有些人在他们的lambda函数的代码中使用sys模块将这个子目录(在这种情况下出售)添加到他们的python路径中......我不是那个作为解决方案的粉丝,因为它意味着需要为每个lambda函数执行此操作并添加额外的锅炉板代码的需要。我最终使用的解决方案是修改PYTHONPATH运行时环境变量以包含我的子目录。例如,在我的serverless.yml中,我有:

provider:
  environment:
    PYTHONPATH: '/var/task/vendored:/var/runtime'

通过将此设置为此级别的环境变量,它将应用于您在serverless.yml中部署的每个lambda函数 - 如果由于某种原因您不想要,也可以在每个lambda函数级别指定它它适用于所有人。

我不确定如何自我引用PYTHONPATH的现有值以确保在添加我的自定义路径“/ var / task / vendored”的过程中我没有错误地覆盖它... ...很想知道如果有其他人的话。