python

时间:2016-02-11 13:40:32

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

我正在创建一个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

创建了zip项目-dir目录的内容并上传到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

请帮我调试错误。

25 个答案:

答案 0 :(得分:83)

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

请在下面找到快照。 enter image description here

答案 1 :(得分:44)

如果您要上传zip文件。确保您正在压缩目录的内容而不是目录本身。

答案 2 :(得分:21)

此问题的另一个来源是对压缩文件的权限。 必须至少在全球范围内可读。 (分chmod 444

我在python文件上运行了以下内容,然后将其压缩并且工作正常。

chmod u=rwx,go=r

答案 3 :(得分:12)

我发现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”
  4. 使用这些值,您需要将处理程序(如屏幕截图所示)重命名为“cool.lambda_handler”。这是摆脱“无法导入模块'lambda_function'”errorMessage的一种方法。如果你要将python脚本中的处理程序重命名为“sup”,那么你需要将lambda仪表板中的处理程序重命名为“cool.sup”

答案 4 :(得分:8)

为AWS Lambda(Python)创建部署包时,只有很多 gotchas 。我花了几个小时来调试会话,直到找到一个很少失败的公式。

我创建了一个自动化整个过程的脚本,因此不易出错。我还编写了教程,解释了一切是如何工作的。你可能想看一下:

Hassle-Free Python Lambda Deployment [Tutorial + Script]

答案 5 :(得分:5)

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

答案 6 :(得分:4)

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

使用zip命令修复错误:

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

答案 7 :(得分:3)

这是一个快速的步骤。

假设您有一个名为deploy的文件夹,其中的lambda文件位于调用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

最后,您需要将zip文件夹中的所有内容deploy压缩到一个压缩文件中。在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文件并为Lambda指定<file_name>.<function_name>进入您的进程,例如上述示例中的lambda_function.lambda_handler

答案 8 :(得分:1)

2019年的观点:

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

然后,我必须导入一个外部依赖关系,然后按照AWS OPs的指示进行操作。 (本地安装-> zip->上传)。

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

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

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

答案 9 :(得分:1)

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

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

答案 10 :(得分:1)

在lambda_handler中,格式必须为lambda_filename.lambda_functionName 假设如果您要运行lambda_handler函数,并且如果它在lambda_fuction.py中,则您的处理程序格式为“ lambda_function.lambda_handler”。出现错误的另一个原因是模块依赖性。  您的lambda_fuction.py必须位于zip的根目录中。

答案 11 :(得分:1)

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

答案 12 :(得分:0)

@nithin, AWS在TestFixtureB函数中发布了layers概念。您可以创建图层,并在其中上传尽可能多的库,然后可以将图层与lambda函数连接。 有关更多详细信息:https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html

答案 13 :(得分: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>

答案 14 :(得分: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/

答案 15 :(得分: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

答案 16 :(得分:0)

确保将文件夹中的所有依赖项压缩为 python / [您的所有依赖项] ,以使其按照本文档的要求工作。

https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-path

答案 17 :(得分: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

答案 18 :(得分:0)

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

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

答案 19 :(得分:0)

请在Import requests之后添加下面的一个

import boto3

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

答案 20 :(得分:0)

没有必要搞乱。

使用python-lambda

https://github.com/nficano/python-lambda

使用单个命令pylambda deploy 它会自动部署您的功能

答案 21 :(得分:0)

您在 zip 中的包目录也必须是世界可读的。

要确定这是否是您的问题 (Linux),请使用:

find $ZIP_SOURCE -type d -not -perm /001 -printf %M\ "%p\n"

修复使用:

find $ZIP_SOURCE  -type d -not -perm /001 -exec chmod o+x {} \;

文件可读也是一个要求。要确定这是否是您的问题,请使用:

find $ZIP_SOURCE -type f -not -perm /004 -printf %M\ "%p\n"

修复使用:

find $ZIP_SOURCE  -type f -not -perm /004 -exec chmod o+r {} \;

如果您遇到这个问题并且您在 Linux 中工作,请检查在创建或检出 git python 包时是否正确设置了 umask,例如把它放在你的打包脚本或 .bashrc 中:

umask 0002 

答案 22 :(得分:0)

将python文件名更改为lambda_function.py,例如在我的情况下文件名是app.py 一旦我将文件名更改为 lambda_function.py

,错误就消失了

答案 23 :(得分:0)

TL;DR,试试 chmod 755 python

我知道这是一个很长的话题,但是如果您在阅读了所有社区成员在此处发布的所有潜在解决方案后仍然无法解决以下问题,您可以尝试解决我的问题的解决方案。

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

明确地说,我指的是适用于 Python 运行时的 AWS Lambda 层的 zip 文件(不是部署包)。就我而言,所有依赖项都根据 doc 放置在名为 python 的文件夹下。

AWS Lambda Include library dependencies in a layer

请注意,使用名为 python 的文件夹比其他文件夹结构更好,因为它不依赖于 Python 的版本。

那么您应该尝试使用以下代码片段在 Lambda 中执行 ls

import os

def lambda_handler(event, context):
    print(os.listdir('/opt'))
    print(os.listdir('/opt/python'))

这是预期的输出:

['python']
['OpenSSL', '__pycache__', ... 'urllib3', 'urllib3-1.24.2.dist-info']

就我而言,在问题解决之前,输出是

{
  "errorMessage": "[Errno 13] Permission denied: '/opt/python'",
  "errorType": "PermissionError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 16, in lambda_handler\n    print(os.listdir('/opt/python'))\n"
  ]
}

因此,这显然是一个权限问题。执行chmod 755 pythonzip -r9 lambda-layer python并将lambda-layer.zip上传到Lambda后,问题解决。

答案 24 :(得分:0)

我是通过容器而不是 zip 文件构建 lambda。

在我的案例中解决这个问题的是将项目复制到“${LAMBDA_TASK_ROOT}”文件夹中,而不仅仅是我选择的自定义文件夹。

FROM public.ecr.aws/lambda/python:3.8

WORKDIR ${LAMBDA_TASK_ROOT}
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
CMD ["lambda_function.lambda_handler"]

即使我之前设置了 WORKDIR,甚至尝试在 Lambda 中使用“WORKDIR override”设置,它也仅在我使用“${LAMBDA_TASK_ROOT}”文件夹时才有效。