我遇到了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一样简单),而是通过避免根目录中的其他文件夹来保持我的文件结构更清晰。
答案 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”的过程中我没有错误地覆盖它... ...很想知道如果有其他人的话。