python中的AWS Lambda导入模块错误


93

我正在创建一个AWS Lambda python部署程序包。我正在使用一个外部依赖项请求。我使用AWS文档http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html安装了外部依赖项。以下是我的python代码。

import requests

print('Loading function')

s3 = boto3.client('s3')


def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))

    # Get the object from the event and show its content type
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key']).decode('utf8')
    try:
        response = s3.get_object(Bucket=bucket, Key=key)
        s3.download_file(bucket,key, '/tmp/data.txt')
        lines = [line.rstrip('\n') for line in open('/tmp/data.txt')]
        for line in lines:
            col=line.split(',')
            print(col[5],col[6])
        print("CONTENT TYPE: " + response['ContentType'])
        return response['ContentType']
    except Exception as e:
        print(e)
        print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
        raise e

创建了project-dir目录的Zip内容,并将其上传到lambda(Zip目录内容,而不是目录)。当我执行函数时,出现以下错误。

START RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058 Version: $LATEST
**Unable to import module 'lambda_function': No module named lambda_function**

END RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058
REPORT RequestId: 9e64e2c7-d0c3-11e5-b34e-75c7fb49d058  Duration: 19.63 ms  Billed Duration: 100 ms     Memory Size: 128 MB Max Memory Used: 9 MB

请帮助我调试错误。


这是您的完整代码吗?由于该错误,似乎某个地方想要import lambda_function找到某个东西而找不到。也许你想要from future import lambda_function?或者只是在cmd行上pip install lambda_function
Berci'2

@Berci我在AWS平台上运行此python代码。我不能使用点子。我代码中的任何地方都使用lambda_function。如果我在AWS控制台中复制粘贴了相同的代码,它将可以正常工作
Nithin K Anil

请参阅对此主题的最新评论-也许适用于您?
kwinkunks,2016年

@kwinkunks我尝试过了。实际上是在压缩内容而不是目录!
Nithin K Anil

2
我的猜测是函数中的“处理程序”选项不正确。检查您的文件名“ lambda_function.py”和处理程序方法是否为“ lambda_handler”
Vor

Answers:


110

错误是由于lambda函数的文件名引起的。创建lambda函数时,它将要求Lambda函数处理程序。您必须将其命名为Python_File_Name.Method_Name。在这种情况下,我将其命名为lambda.lambda_handler(lambda.py是文件名)。

请在快照下方找到。 在此处输入图片说明


1
我的代码只是lambda中的代码-而不是文件。
本·惠勒

4
@BenWheeler:尽管它是内联代码,但实际上是您编写的文件。您可以在窗口左侧看到文件名和整个目录结构。
Vineeth '18

因此,我已将代码命名为“ lambda_function.py”,是否应将处理程序命名为Python_lambda_function.lambda_handler?
RB17

@RahulBanerjee号,您可以将其称为lambda_function.lambda_handler
Dinesh


24

此问题的另一个来源是对压缩文件的权限。它必须至少是全世界可读的。(分钟chmod 444

在压缩之前,我在python文件上运行了以下命令,它工作正常。

chmod u=rwx,go=r

4
这个。我使用Python的ZipFile以编程方式将lambda函数打包到ZIP中,它默认为具有0600您所提到的不够的功能。此外,集成的Lambda源代码编辑器(在Amazon网页上)将愉快地读取文件,而不会警告权限问题。
cjhanks

2
第二。我通过使用此处显示的方法设置文件权限来使其工作:stackoverflow.com/a/434689/931277
dokkaebi

15

我发现Nithin的回答非常有帮助。这是一个具体的演练:

查找以下值:

  1. python脚本中的lambda_handler函数的名称。AWS示例中使用的名称是“ lambda_handler”,看起来像“ def lambda_handler(event,context)”。在这种情况下,值为“ lambda_handler”
  2. 在Lambda仪表板中,在该功能的lambda仪表板“配置”部分的“处理程序”文本框中找到处理程序的名称(如Nithin的屏幕快照所示)。我的默认名称是“ lambda_function.lambda_handler”。
  3. 您的python脚本的名称。假设它是“ cool.py”

使用这些值,您需要将处理程序(如屏幕快照中所示)重命名为“ cool.lambda_handler”。这是摆脱“无法导入模块'lambda_function'”错误消息的一种方法。如果要将python脚本中的处理程序重命名为“ sup”,则需要将lambda仪表板中的处理程序重命名为“ cool.sup”


11

为AWS Lambda(用于Python)创建部署程序包时有很多陷阱。我花了数小时的时间进行调试会话,直到找到一个很少失败的公式。

我创建了一个脚本,该脚本可以使整个过程自动化,因此可以减少出错的可能性。我还写了一篇教程,解释了一切工作原理。您可能需要检查一下:

轻松的Python Lambda部署[教程+脚本]


2
很棒的帖子,但是我想念最难的部分是如何打包本地库。这到底有多复杂,这真的很不正常
JohnAndrews

10

这是一个快速的步骤。

假设您有一个名为的文件夹deploy,其中的lambda文件位于call中lambda_function.py。假设该文件看起来像这样。(p1p2代表第三方软件包。)

import p1
import p2

def lambda_handler(event, context):
    # more code here

    return {
        "status": 200,
        "body" : "Hello from Lambda!",
    }

对于每个第三方依赖性,您都需要pip install <third-party-package> --target .从该deploy文件夹中进行。

pip install p1 --target .
pip install p2 --target .

完成此操作后,您的结构应如下所示。

deploy/
├── lambda_function.py
├── p1/
│   ├── __init__.py
│   ├── a.py
│   ├── b.py
│   └── c.py
└── p2/
    ├── __init__.py
    ├── x.py
    ├── y.py
    └── z.py

最后,您需要zipdeploy文件夹内的所有内容转换为压缩文件。在Mac或Linux上,该命令zip -r ../deploy.zip *deploy文件夹中看起来像。请注意,该-r标志用于递归子文件夹。

文件zip文件的结构应镜像原始文件夹。

deploy.zip/
├── lambda_function.py
├── p1/
│   ├── __init__.py
│   ├── a.py
│   ├── b.py
│   └── c.py
└── p2/
    ├── __init__.py
    ├── x.py
    ├── y.py
    └── z.py

上载zip文件,并指定<file_name>.<function_name>Lambda进入您的流程,lambda_function.lambda_handler例如上面的示例。


1
此外,请勿像那样压缩整个文件夹zip -r deploy.zip deploy。这将在zip文件中创建一个deploy文件夹。
openwonk

9

在尝试了上述所有解决方案后,我发现了这种困难的方式。如果您在zip文件中使用子目录,请确保__init__.py在每个子目录中都包含该文件,并且该文件对我有用。


7

我也有错误。原来我的zip文件包含代码父文件夹。当我unzip检查zip文件时,该lambda_function文件位于父文件夹之下./lambda

使用zip命令,修复错误:

zip -r ../lambda.zip ./*

1
在您的代码文件夹中运行zip文件。我的情况是cd lambda && zip -r ../lambda.zip ./*

4

lambda_handler格式必须是lambda_filename.lambda_functionName。假设您要运行该lambda_handler函数,并且该函数位于中lambda_fuction.py,则处理程序格式为lambda_function.lambda_handler

出现此错误的另一个原因是模块依赖性。

lambda_fuction.py必须位于zip文件的根目录中。



2

来自2019年的观点:

AWS Lambda现在支持Python 3.7,许多人(包括我自己)选择将其用作内联lambda的运行时。

然后,我必须导入一个外部依赖项,然后按照称为OP的方式遵循AWS Docs。(本地安装-> zip->上传)。

我遇到导入模块错误,并且意识到我的本地PC使用Python 2.7作为默认Python。当我调用pip时,它安装了我对Python 2.7的依赖。

因此,我在本地切换到与Lambda控制台中选定的运行时版本匹配的Python版本,然后重新安装了外部依赖项。这为我解决了问题。例如:

$ python3 -m pip install --target path/to/lambda_file <external_dependency_name>

1

我遇到了同样的问题,如果我没有记错的话,这是lynda.com上教程的一部分。我犯的错误是没有将运行时选择为Python 3.6,这是lamda函数控制台中的一个选项。


1

此处用于构建Lambda函数依赖关系(在您自己的计算机上)的Python版本与为Lambda函数选择的Python版本不同。这种情况很常见,特别是如果依赖项中的Numpy库部分。

示例:您机器的python版本:3.6 ---> Lambda python版本3.6


0

您需要压缩所有要求,使用此脚本

#!/usr/bin/env bash
rm package.zip
mkdir package
pip install -r requirements.txt --target package
cat $1 > package/lambda_function.py
cd package
zip -r9 "../package.zip" .
cd ..
rm -rf package

用于:

package.sh <python_file>

0

为同一问题分享我的解决方案,以防万一它对任何人都有帮助。

问题:我收到错误:“ [ERROR] Runtime.ImportModuleError:无法导入模块'lambda_function':没有名为'StringIO'的模块”,在执行AWS文章[2]中提供的aws-big-data-blog代码[1]时。

解决方案:将运行时从Python 3.7更改为Python 2.7

[1] -https: //github.com/bsnively/aws-big-data-blog/blob/master/aws-blog-vpcflowlogs-athena-quicksight/CloudwatchLogsToFirehose/lambdacode.py [2] -https:// aws .amazon.com / blogs / big-data / analyzing-vpc-flow-logs-with-amazon-kinesis-firehose-amazon-athena-and-amazon-quicksight /


对我而言,这是另一种方式(2.7-> 3.8)
demonicdaron

0

您可以配置Lambda函数以层的形式引入其他代码和内容。层是一个ZIP归档文件,其中包含库,自定义运行时或其他依赖项。通过层,您可以在函数中使用库,而无需在部署包中包括它们。分层使您可以减小部署程序包的大小,从而使开发更加容易。

参考文献:

  1. https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html
  2. https://towardsdatascience.com/introduction-to-amazon-lambda-layers-and-boto3-using-python3-39bd390add17


0

我的问题是.py文件和依赖项不在zip的“根”目录中。例如,库和lambda函数.py的路径必须为:

<lambda_function_name>.py
<name of library>/foo/bar/

/foo/bar/<name of library>/foo2/bar2

例如:

drwxr-xr-x  3.0 unx        0 bx stor 20-Apr-17 19:43 boto3/ec2/__pycache__/
-rw-r--r--  3.0 unx      192 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/__init__.cpython-37.pyc
-rw-r--r--  3.0 unx      758 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/deletetags.cpython-37.pyc
-rw-r--r--  3.0 unx      965 bx defX 20-Apr-17 19:43 boto3/ec2/__pycache__/createtags.cpython-37.pyc
-rw-r--r--  3.0 unx     7781 tx defN 20-Apr-17 20:33 download-cs-sensors-to-s3.py

0

实际上转到您要压缩的主文件夹(部署程序包),

在该文件夹中,选择所有文件,然后创建zip并上传该zip


0

请在下面加一个 Import requests

import boto3

我看到的是您的代码中缺少的内容。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.