代码之家  ›  专栏  ›  技术社区  ›  Harry

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

  •  10
  • Harry  · 技术社区  · 8 年前

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

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

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

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

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

    一定有一个指向子文件夹的配置我没有找到,但google没有透露我是否需要以其他方式导入模块,或者是否需要更改其他全局配置。

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

    编辑 :注意到tkwargs关于使用无服务器插件进行打包的好建议,例如,了解在没有venv的情况下如何实现这一点仍然很好。其主要目的并不是为了使打包更容易(与pip一样很容易),而是通过避免在根目录中添加其他文件夹来保持文件结构更干净。

    1 回复  |  直到 8 年前
        1
  •  9
  •   kinzleb    8 年前

    我见过一些人在其lambda函数的代码中使用sys模块将子目录(本例中提供)添加到python路径中。。。我不喜欢将其作为解决方案,因为这意味着需要为每个lambda函数都这样做,并需要添加额外的锅炉板代码。我最终使用的解决方案是修改PYTHONPATH运行时环境变量以包含我的子目录。例如,在my serverless中。yml我有:

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

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

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