是否可以通过serverless.yml向PATH环境变量添加路径?
Is it possible to add paths to the PATH environment variable through serverless.yml?
当我创建 AWS Lambda 层时,我的 zip 文件的所有内容/模块都会在 AWS Lambda 执行时转到 /opt/
。这很容易变得麻烦和令人沮丧,因为我必须在我所有的 lambda 上使用绝对导入。示例:
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
,而不是那种怪异的丑陋。
您是否尝试过设置 PYTHONPATH 环境变量?
您尝试过添加到 sys.path 吗?
我有 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
在 zip 存档中,模块需要放在 python
子目录中,以便在 Lambda 中将其提取为层时,它位于 /opt/python
中。这样你就可以直接导入你的模块而不需要 importlib
。
来自 AWS 开发布道师的 documented here or see this detailed blogpost 更多信息。
不需要设置 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
}
当我创建 AWS Lambda 层时,我的 zip 文件的所有内容/模块都会在 AWS Lambda 执行时转到 /opt/
。这很容易变得麻烦和令人沮丧,因为我必须在我所有的 lambda 上使用绝对导入。示例:
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
,而不是那种怪异的丑陋。
您是否尝试过设置 PYTHONPATH 环境变量?
您尝试过添加到 sys.path 吗?
我有 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
在 zip 存档中,模块需要放在 python
子目录中,以便在 Lambda 中将其提取为层时,它位于 /opt/python
中。这样你就可以直接导入你的模块而不需要 importlib
。
来自 AWS 开发布道师的 documented here or see this detailed blogpost 更多信息。
不需要设置 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
}