5

当我创建 AWS Lambda 层时,我的 zip 文件的所有内容/模块都会/opt/在 AWS Lambda 执行时转到。这很容易变得麻烦和令人沮丧,因为我必须在我的所有 lambdas 上使用绝对导入。例子:

import json
import os
import importlib.util
spec = importlib.util.spec_from_file_location("dynamodb_layer.customer", "/opt/dynamodb_layer/customer.py")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

def fetch(event, context):

    CustomerManager = module.CustomerManager
    customer_manager = CustomerManager()

    body = customer_manager.list_customers(event["queryStringParameters"]["acquirer"])

    response = {
        "statusCode": 200,
        "headers": {
            "Access-Control-Allow-Origin": "*"
        },
        "body": json.dumps(body)
    }

    return response

所以我想知道,是否可以通过 serverless.yml 预先将这些 /opt/paths 添加到 PATH 环境变量中?这样一来,我就可以from dynamodb_layer.customer import CustomerManager,而不是那种怪异的丑陋。

4

4 回答 4

1

我有用于 Python3.6 运行时的 Lambda 层。我的 my_package.zip 结构是:

my_package.zip
 - python
   - lib
     - python3.6
       - site-packages
         - customer

所有依赖项都build在项目根目录中:例如build/python/lib/python3.6/site-packages/customer

我的 serverless.yml 的相关部分

layers:
  my_package:
    path: build             
    compatibleRuntimes:     
      - python3.6

在我的 Lambda 中,我像导入任何其他包一样导入我的包: import customer

于 2019-01-11T22:00:20.203 回答
0

您是否尝试过设置 PYTHONPATH 环境变量? https://stackoverflow.com/a/5944201/6529424

您是否尝试添加到 sys.path? https://stackoverflow.com/a/12257807/6529424

于 2019-01-11T19:41:50.110 回答
0

不需要设置 PYTHONPATH 变量,只要将项目正确放置在 zip 文件中即可。

简单的模块和包目录,这些应该放在目录“python”中,然后将整个 python/ 放入 zip 文件中,以作为层上传到 AWS。不要忘记为图层添加“兼容的运行时”(例如 Python 3.6、3.7、3.8 ...)设置。

举个例子:

python/
- my_module.py
- my_package_dir
-- __init__.py
-- package_mod_1.py
-- package_mod_2.py

然后将其包含在 zip 文件中。

zip -r my_layer_zip.zip python/

当作为层访问时,可以毫不费力地导入模块:

....
import my_module
from my_package.package_mod_2 import mod_2_function
....

如果您查看“/opt/python/”,您可以从 lambda 中看到包结构,它将显示 my_module.py、my_package/ 等,这很容易使用 AWS Lambda 测试函数进行测试,假设该层附加到函数(否则代码会出错)

import json
import os

def lambda_handler(event, context):
    # TODO implement

    dir_list = os.listdir('/opt/python/')

    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!'),
        'event': json.dumps(event),
        '/opt/python/': dir_list
    }
于 2020-12-03T14:40:21.960 回答
0

在 zip 存档中,需要将模块放置在python子目录中,以便在 Lambda 中将其作为层提取时,它位于/opt/python. 这样你就可以直接导入你的模块而不需要importlib.

此处记录或查看来自 AWS 开发布道者的详细博文了解更多信息

于 2019-01-12T14:46:19.350 回答