如何修复 AWS lambda 中的 "Unable to import module" 错误
How to fix "Unable to import module" error in AWS lambda
我写了一个脚本来帮助我自动创建新的微服务。它通过获取 bitbucket 存储库的 URI 和 AWS 凭证来工作。它克隆存储库,添加一个 bitbucket-pipelines.yml 文件。通过调用 CLI 并使用模板 zip 作为基本代码来创建新的 lambda 函数。它还将 lambda 处理程序设置为 main.lambda_handler
。然后它将必要的存储库变量添加到 bitbucket 并提交项目文件。然后管道 运行s 并更新 lambda 上的代码。一切似乎都很好,直到我尝试 运行 Lambda。
这里是 bitbucket-pipelines.yml 文件
image: peteremil/zipaws
pipelines:
default:
- step:
name: Deploy code to S3
deployment: staging
script:
- mkdir packages
- pip install -r requirements.txt --target=packages
- chmod 777 -R *
- zip -r $semver.zip .
- aws s3 cp $semver.zip s3://{code_s3_bucket}/$staging_location/
- aws lambda update-function-code --region $aws_region --function-name {function_name}-function --s3-bucket {code_s3_bucket} --s3-key $staging_location/$semver.zip
这是 main.py 文件
import json
import os
import sys
import requests
packages_path = os.path.join(os.path.split(__file__)[0], "packages")
sys.path.append(packages_path)
def main(local_id):
return {
"success" : local_id
}
def lambda_handler(event, context):
local_id = event["queryStringParameters"]["local_id"]
response = main(local_id)
return {
"statusCode": 200,
"headers": {"content-type": "application/json"},
"body": json.dumps(response)
}
if __name__ == '__main__':
local_id = sys.argv[-1]
response = main(local_id)
print(response)
我创建了以下测试事件
{
"queryStringParameters": {
"local_id": "00000000"
}
}
我创建的事件的预期结果应该是
{
"statusCode": 200,
"headers" : {"content-type": "application/json"},
"body" : {
{
"success" : "00000000"
}
}
但是 lambda 执行失败并给了我
{
"errorMessage": "Unable to import module 'main'"
}
我尝试重命名处理程序,获取另一个工作 lambda 的设置(从控制台手动创建)并查看是否有任何差异,但我总是遇到相同的错误。 main.py 文件在内联代码编辑器中显示正常。
更新 1
我将 import requests
行添加到 main.py 中,因为事实证明这是导致问题的原因。我认为它是无害的,这就是为什么我没有将它包含在原始问题正文中的原因。
事实证明,在我的代码中,我在 packages\
文件夹中导入了一个库,但我在将文件夹添加到 sys.path
之前导入了它,所以解决方案是 import requests
将 packages_path
路径添加到 sys.path
.
之后
main.py现在这样开始
import json
import os
import sys
packages_path = os.path.join(os.path.split(__file__)[0], "packages")
sys.path.append(packages_path)
import requests #moved this line down after adding packages_path to sys.path
我写了一个脚本来帮助我自动创建新的微服务。它通过获取 bitbucket 存储库的 URI 和 AWS 凭证来工作。它克隆存储库,添加一个 bitbucket-pipelines.yml 文件。通过调用 CLI 并使用模板 zip 作为基本代码来创建新的 lambda 函数。它还将 lambda 处理程序设置为 main.lambda_handler
。然后它将必要的存储库变量添加到 bitbucket 并提交项目文件。然后管道 运行s 并更新 lambda 上的代码。一切似乎都很好,直到我尝试 运行 Lambda。
这里是 bitbucket-pipelines.yml 文件
image: peteremil/zipaws
pipelines:
default:
- step:
name: Deploy code to S3
deployment: staging
script:
- mkdir packages
- pip install -r requirements.txt --target=packages
- chmod 777 -R *
- zip -r $semver.zip .
- aws s3 cp $semver.zip s3://{code_s3_bucket}/$staging_location/
- aws lambda update-function-code --region $aws_region --function-name {function_name}-function --s3-bucket {code_s3_bucket} --s3-key $staging_location/$semver.zip
这是 main.py 文件
import json
import os
import sys
import requests
packages_path = os.path.join(os.path.split(__file__)[0], "packages")
sys.path.append(packages_path)
def main(local_id):
return {
"success" : local_id
}
def lambda_handler(event, context):
local_id = event["queryStringParameters"]["local_id"]
response = main(local_id)
return {
"statusCode": 200,
"headers": {"content-type": "application/json"},
"body": json.dumps(response)
}
if __name__ == '__main__':
local_id = sys.argv[-1]
response = main(local_id)
print(response)
我创建了以下测试事件
{
"queryStringParameters": {
"local_id": "00000000"
}
}
我创建的事件的预期结果应该是
{
"statusCode": 200,
"headers" : {"content-type": "application/json"},
"body" : {
{
"success" : "00000000"
}
}
但是 lambda 执行失败并给了我
{
"errorMessage": "Unable to import module 'main'"
}
我尝试重命名处理程序,获取另一个工作 lambda 的设置(从控制台手动创建)并查看是否有任何差异,但我总是遇到相同的错误。 main.py 文件在内联代码编辑器中显示正常。
更新 1
我将 import requests
行添加到 main.py 中,因为事实证明这是导致问题的原因。我认为它是无害的,这就是为什么我没有将它包含在原始问题正文中的原因。
事实证明,在我的代码中,我在 packages\
文件夹中导入了一个库,但我在将文件夹添加到 sys.path
之前导入了它,所以解决方案是 import requests
将 packages_path
路径添加到 sys.path
.
main.py现在这样开始
import json
import os
import sys
packages_path = os.path.join(os.path.split(__file__)[0], "packages")
sys.path.append(packages_path)
import requests #moved this line down after adding packages_path to sys.path