【问题标题】:How to deploy Python AWS Lambda with its dependencies using Javascript AWS CDK?如何使用 Javascript AWS CDK 部署 Python AWS Lambda 及其依赖项?
【发布时间】:2021-12-18 07:47:57
【问题描述】:

我有一个使用 javascript 构建的 AWS CDK 堆栈。 Stack 有多个 lambda。它们中的大多数都在 javascript 中。我想在 python 中添加一个 lambda。当我不导入外部依赖项时,python lambda 工作正常,但在我安装它们时不理解。我尝试将软件包安装在 package 文件夹或 python 文件夹中,并按照这些文章的建议进行压缩,但没有成功:

https://docs.aws.amazon.com/lambda/latest/dg/python-package.html https://aws.amazon.com/premiumsupport/knowledge-center/lambda-import-module-error-python/

我得到的错误是"Unable to import module 'py1': No module named 'x'" (x 指的是我尝试导入的任何包名)

我的 javascript CDK 库代码是这样的:

// javascript lambda
new lambda.Function(this, 'lambda-js1', {
  functionName: `js1`,
  code: lambda.Code.fromAsset('assets/lambdajs'),
  handler: 'js1.handler',
  runtime: lambda.Runtime.NODEJS_14_X,
})

// python lambda
new lambda.Function(this, 'lambda-py1', {
  functionName: `py1`,
  code: lambda.Code.fromAsset('assets/lambdapy'),
  handler: 'py1.handler',
  runtime: lambda.Runtime.PYTHON_3_8,
})

我使用 assets/lambdapy 安装了依赖项

pip install x
pip install --target ./package x
pip install -t python/ x

之后我把它们拉上拉链

我的python代码在assets/lambdapy/py1.py

# not sure how to import. none of the below worked
import x
import package.x
import python.x

def handler(event, context):
    return { 
        'statusCode': 200
    }

在调用 python lambda 时,我得到

{
  "errorMessage": "Unable to import module 'py1': No module named 'x'",
  "errorType": "Runtime.ImportModuleError",
  "stackTrace": []
}

【问题讨论】:

标签: python amazon-web-services aws-lambda aws-cdk


【解决方案1】:

为 Python 创建一个 Lambda 层。将所有依赖项打包在 zip 文件中,并将其上传到创建的层。 请参考相同的链接https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html

【讨论】:

  • 感谢您的帮助。我做了类似的事情
【解决方案2】:

使用aws-cdk.aws-lambda-python L2 构造,它会自动安装依赖项。

这是文档:

https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-python-readme.html

Typescript 示例来自上述文档:

import * as lambda from "@aws-cdk/aws-lambda";
import { PythonFunction } from "@aws-cdk/aws-lambda-python";

new PythonFunction(this, 'MyFunction', {
  entry: '/path/to/my/function', // required
  index: 'my_index.py', // optional, defaults to 'index.py'
  handler: 'my_exported_func', // optional, defaults to 'handler'
  runtime: lambda.Runtime.PYTHON_3_6, // optional, defaults to lambda.Runtime.PYTHON_3_7
});

它将安装来自诗歌文件、pipfile 或 requiremenets.txt 的依赖项

【讨论】:

  • 我没有尝试,因为它还处于实验阶段,并且还需要 Docker
  • 这是迄今为止最简单的解决方案。请注意,对于当前版本的 CDK(目前为 v2.10),它仍处于 alpha 阶段,这意味着您需要单独安装它 pip install aws-cdk.aws-lambda-python-alpha,然后使用 import aws_cdk.aws_lambda_python_alpha as aws_lambda_python 导入它。虽然这个特殊的结构可能只是自己创建了一个层,但我发现它很混乱,并且需要在我的应用程序中创建一个层来为单个 lambda 添加 deps。
  • 我要补充一点,我在这里找到了自己,因为我正在使用标准构造 lambda.Function 创建一个 lambda,并使用 Code.fromDockerBuild 指定代码,因为我需要添加一些其他系统库。走这条路,似乎唯一的解决方案可能是添加一个层,这很烦人,因为 PythonFunction 构造在其他方面工作得很好。
【解决方案3】:

我的解决方案

首先,我在assets/lambdapylibs 中安装了两次依赖项(一个在本地机器上工作,一个在 lambda 上工作)

# to work on local machine
pip install x

# to work on lambda. it has to be under python folder (assets/lambdapylibs/python)
pip install --target ./python x

其次,我编码assets/lambdapy/py1.py并正常导入x

import x

def handler(event, context):
    return { 
        'statusCode': 200
    }

第三,我在我的 javascript CDK 库中添加了一个层。该层具有python依赖项

// javascript lambda
new lambda.Function(this, 'lambda-js1', {
  functionName: `js1`,
  code: lambda.Code.fromAsset('assets/lambdajs'),
  handler: 'js1.handler',
  runtime: lambda.Runtime.NODEJS_14_X,
})

// python libs layer
const layerPythonLibs = new lambda.LayerVersion(this, 'layer-python-libs', {
  code: lambda.Code.fromAsset('assets/lambdapylibs'),
  compatibleRuntimes: [lambda.Runtime.PYTHON_3_8],
})

// python lambda
new lambda.Function(this, 'lambda-py1', {
  functionName: `py1`,
  code: lambda.Code.fromAsset('assets/lambdapy'),
  handler: 'py1.handler',
  runtime: lambda.Runtime.PYTHON_3_8,
  layers: [layerPythonLibs],
})

【讨论】:

    猜你喜欢
    • 2021-04-08
    • 2017-10-28
    • 1970-01-01
    • 2021-07-25
    • 2017-07-15
    • 2020-04-25
    • 1970-01-01
    • 2016-04-16
    • 2016-08-24
    相关资源
    最近更新 更多