【问题标题】:Google Cloud Platform API for Python and AWS Lambda Incompatibility: Cannot import name 'cygrpc'适用于 Python 和 AWS Lambda 的 Google Cloud Platform API 不兼容:无法导入名称“cygrpc”
【发布时间】:2019-03-25 13:53:39
【问题描述】:

我正在尝试将适用于 Python 的 Google Cloud Platform(特别是 Vision API)与 AWS Lambda 结合使用。因此,我必须为我的依赖项创建一个部署包。但是,当我尝试创建此部署包时,无论 Python 的版本是什么(3.6 或 2.7),都会出现一些编译错误。考虑到 3.6 版,我收到“无法导入名称 'cygrpc'”的问题。对于 2.7,.path 文件出现一些未知错误。我正在遵循 AWS Lambda 部署包说明here。他们推荐了两个选项,两者都不起作用/导致相同的问题。 GCP 是否出于某种原因与 AWS Lambda 不兼容?有什么关系?

Python 3.6 和 2.7 都不适合我。

注意:我在这里发布这个问题是为了自己回答,因为我花了很长时间才找到解决方案,我想分享我的解决方案。

【问题讨论】:

    标签: python-3.x amazon-web-services google-cloud-platform aws-lambda


    【解决方案1】:

    TL;DR:您无法在您的 Mac 或您使用的任何电脑上编译部署包。您必须使用特定的操作系统/“设置”来执行此操作,这与 AWS Lambda 用于运行您的代码的设置相同。为此,您必须使用 EC2。

    我将在此处提供有关如何让 Google Cloud Vision 在 AWS Lambda for Python 2.7 上运行的答案。对于 AWS Lambda 上的其他 API 和其他编程语言,此答案可能是可扩展的。

    因此,我的解决方案之旅始于 Github 上的 this initial posting,其他人也有同样的问题。有人发布的一种解决方案是

    我在运行时遇到了同样的问题“无法导入名称 'cygrpc'” 拉姆达。在 AMI 中使用 pip install google-cloud-vision 解决了这个问题 amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2 实例并导出 lib/python3.6/site-packages 到 aws lambda 谢谢@tseaver

    这是部分正确的,除非我读错了,但不管它引导我走上正确的道路。您将不得不使用 EC2。以下是我采取的步骤:

    1. 通过转至 Amazon 上的 EC2 设置 EC2 实例。如果您还没有,请快速阅读 AWS EC2。为 amzn-ami-hvm-2018.03.0.20180811-x86_64-gp2 或类似的东西(即最新的)设置一个。
    2. 获取您的 EC2 .pem 文件。转到您的终端。 cd 进入 .pem 文件所在的文件夹。使用

      SSH 进入您的实例

      ssh -i "your-file-name-here.pem" ec2-user@ec2-ip-address-here.compute-1.amazonaws.com

    3. 使用 mkdir 在您的实例上创建以下文件夹:google-cloud-vision、protobuf、google-api-python-client、httplib2、uritemplate、google-auth-httplib2。

    4. 在您的 EC2 实例上,cd 进入 google-cloud-vision。运行命令:

      pip install google-cloud-vision -t .

    注意如果出现“bash: pip: command not found”,则输入“sudo easy_install pip”source

    1. 使用以下软件包重复第 4 步,同时 cd'ing 到相应的文件夹:protobuf、google-api-python-client、httplib2、uritemplate、google-auth-httplib2。

    2. 复制计算机上的每个文件夹。您可以使用 scp 命令执行此操作。同样,在您的终端中,而不是您的 EC2 实例,而不是您用于访问 EC2 实例的终端窗口中,运行命令(以下是您的“google-cloud-vision”文件夹的示例,但对每个文件夹重复此操作):

      sudo scp -r -i your-pem-file-name.pem ec2-user@ec2-ip-address-here.compute-1.amazonaws.com:~/google-cloud-vision ~/Documents/your -本地目录/

    3. 从 AWS 控制台停止您的 EC2 实例,以免被多收费用。

    4. 对于您的部署包,您需要一个包含所有模块和 Python 脚本的文件夹。要开始组合所有模块,请创建一个名为“模块”的空文件夹。将“google-cloud-vision”文件夹的所有内容复制并粘贴到“modules”文件夹中。现在只将“protobuf”(原文如此)主文件夹中标题为“protobuf”的文件夹放在“modules”文件夹的“Google”文件夹中。同样从“protobuf”主文件夹中,将 Protobuf .pth 文件和 -info 文件夹粘贴到 Google 文件夹中。

    5. 对于 protobuf 之后的每个模块,将标题为模块名称的文件夹、.pth 文件和“-info”文件夹复制并粘贴到“modules”文件夹中。

    6. 您现在已经正确组合了所有模块(几乎)。要完成组合,请从“模块”文件夹中删除这两个文件:googleapis_common_protos-1.5.3-nspkg.pth 和 google_cloud_vision-0.34.0-py3.6-nspkg.pth。将“模块”文件夹中的所有内容复制并粘贴到您的部署包文件夹中。此外,如果您使用 GCP,请同时粘贴 .json 文件以获取您的凭据。

    7. 最后,将您的 Python 脚本放入此文件夹,压缩 内容(不是文件夹),上传到 S3,然后将链接粘贴到您的 AWS Lambda 函数中,然后开始吧!

    如果此处的某些内容与描述的不符,请原谅我并给我发消息或随时编辑我的答案。希望这会有所帮助。

    【讨论】:

    • 谢谢!很长一段时间以来一直试图解决这个问题,这很有效!
    • @Nour 没问题,我很乐意提供帮助!
    【解决方案2】:

    基于@Josh Wolff 的答案(非常感谢,顺便说一句!),这可以通过使用 Amazon 提供的 Lambdas 的 Docker 映像来简化。

    您可以将库与您的项目源捆绑在一起,或者就像我在下面的 Makefile 脚本中所做的那样,将其作为 AWS 层上传。

    layer:
        set -e ;\
        docker run -v "$(PWD)/src":/var/task "lambci/lambda:build-python3.6" /bin/sh -c "rm -R python; pip install -r requirements.txt -t python/lib/python3.6/site-packages/; exit" ;\
        pushd src ;\
        zip -r my_lambda_layer.zip python > /dev/null ;\
        rm -R python ;\
        aws lambda publish-layer-version --layer-name my_lambda_layer --description "Lambda layer" --zip-file fileb://my_lambda_layer.zip --compatible-runtimes "python3.6" ;\
        rm my_lambda_layer.zip ;\
        popd ;
    

    以上脚本将:

    1. 如果您还没有 Docker 映像,请拉取它(以上使用 Python 3.6)
    2. 删除python目录(仅对运行第二个有用 时间)
    3. 将所有需求安装到 python 目录,在您的项目 /src 目录中创建
    4. 压缩python目录
    5. 上传 AWS 层
    6. 删除python目录和zip文件

    确保您的 requirements.txt 文件包含 Josh 上面列出的模块:google-cloud-vision、protobuf、google-api-python-client、httplib2、uritemplate、google-auth-httplib2

    【讨论】:

    • 感谢您的贡献!
    【解决方案3】:

    有一种不需要太多编码的快速解决方案。

    Cloud9 使用 AMI,因此在他们的虚拟环境中使用 pip 应该可以正常工作。

    我从 Cloud9 UI 创建了一个 Lambda,并从控制台激活了 EC2 机器的 venv。我继续使用 pip 安装 google-cloud-speech。这足以解决问题。

    【讨论】:

      【解决方案4】:

      我在使用 goolge-ads API 时遇到了同样的错误。

      { "errorMessage": "无法导入模块 'lambda_function': 无法从 'grpc._cython' (/var/task/grpc/_cython/init.py) 导入名称 'cygrpc'","errorType ": "Runtime.ImportModuleError","stackTrace": []}

      我的 Lambda 运行时是 Python 3.9 和架构 x86_64。

      如果有人遇到类似的 ImportModuleError,请在此处查看我的答案:Cannot import name 'cygrpc' from 'grpc._cython' - Google Ads API

      【讨论】:

        猜你喜欢
        • 2018-03-22
        • 1970-01-01
        • 2019-10-18
        • 2018-09-19
        • 2018-01-01
        • 2021-12-13
        • 1970-01-01
        • 2019-12-03
        相关资源
        最近更新 更多