python - 将 Python 依赖项打包到 AWS Lambda 的子目录中

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

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

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

我已经使用命令 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 一样非常简单),而是通过避免在根目录中添加其他文件夹来保持我的文件结构更清晰。

最佳答案

我看到有些人在他们的 lambda 函数代码中使用 sys 模块来将子目录(在本例中为 vendored)添加到他们的 python 路径中……我不喜欢将其作为解决方案,因为这意味着需要为每个 lambda 函数执行此操作,并需要额外的样板代码。我最终使用的解决方案是修改 PYTHONPATH 运行时环境变量以包含我的子目录。例如,在我的 serverless.yml 中我有:

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

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

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

关于python - 将 Python 依赖项打包到 AWS Lambda 的子目录中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49839924/

相关文章:

python - Paramiko recv_ready() 返回假值

python - 错误 : could not create '/usr/local/lib/python2.7/dist-packages/virtualenv_support' : Permission denied

node.js - 如何在 node.js 中从 AWS Lambda 将原始 JSON 记录到 Cloudwatch?

amazon-web-services - AWS lambda 中的执行器服务

Python的itertools乘积内存消耗

python - 使用 Python 复制和重命名 excel 文件

python - 最常见的字符 - 用户提交的没有字典或计数器的字符串

java - pip和npm有什么区别?

python - 如何在 OSX 上安装 pyperclip

amazon-web-services - 是否可以将 TypeScript 与 'aws-sdk-mock' 一起使用