我看到一篇关于 serverlesscode.com 为AWS Lambda构建Python 3应用程序的文章,建议使用pip(或pip3)在/vendored子目录中安装依赖项。我喜欢这个想法,因为它可以保持文件结构干净,但是我在实现它时遇到了一些问题。
我正在使用无服务器框架,我的模块以正常方式导入到我的代码中,例如from pynamodb.models import Model
我使用命令pip install -t vendored/ -r requirements.txt
在子目录中安装我的各种依赖项(根据要求.txt),这似乎按预期工作 - 我可以看到子目录中安装的所有模块。
但是,当调用该函数时,我收到错误Unable to import module 'handler': No module named 'pynamodb'
(其中pynamodb是已安装的模块之一)。
我可以通过将我的 pip 安装更改为项目根目录来解决此错误,即不在/vendored 文件夹 (pip install -t ./ -r requirements.txt
中)。这将安装完全相同的文件。
一定有一个我缺少指向子文件夹的配置,但谷歌搜索没有透露我是否需要以不同的方式导入我的模块,或者是否有其他一些全局配置需要更改。
总结一下:如何使用 Pip 将依赖项安装在项目的子文件夹中?
编辑 :注意到tkwargs关于使用无服务器插件进行打包的好建议,例如,了解如何在没有venv的情况下完成此操作仍然很好。主要目的不是专门使打包更容易(使用 pip 非常简单),而是通过避免根目录中的其他文件夹来保持我的文件结构更干净。
我见过一些人在他们的 lambda 函数的代码中使用 sys 模块将子目录(在本例中是供应商)添加到他们的 python 路径中......我不喜欢将其作为解决方案,因为这意味着需要为每个 lambda 函数执行此操作,并添加对额外样板代码的需求。 我最终使用的解决方案是修改 PYTHONPATH 运行时环境变量以包含我的子目录。 例如,在我的无服务器.yml中,我有:
provider:
environment:
PYTHONPATH: '/var/task/vendored:/var/runtime'
通过在此级别将其设置为环境变量,它将应用于您在serverless.yml中部署的每个lambda函数 - 如果由于某种原因您不希望将其应用于所有lambda函数,您也可以在每个lambda函数级别指定它。
我不确定如何自我引用 PYTHONPATH 的现有值,以确保我在添加自定义路径"/var/task/vendored"的过程中不会错误地覆盖它......很想知道是否有其他人有。