无法在AWS Lambda上使用Requests模块

102

我需要在每天运行一次的Python脚本中进行REST调用。但是我无法将“requests”包打包到我的Python包中使用AWS Lambdas。我收到错误消息:“Unable to import module 'lambda_function': No module named lambda_function”。

我将其简化为预定义的hello_world脚本。我可以将其打包成zip并上传。一切正常。但是一旦我在文件中放入“import requests”,就会出现此错误。

以下是我已经做过的事情:

  1. zip和项目文件夹(包括子文件夹)的权限设置为“chmod 777”。因此,权限不应该是问题。
  2. 脚本本身位于根文件夹中。打开zip文件时,您可以直接看到它。
  3. 我使用“sudo pip install requests -t PATH_TO_ROOT_FOLDER”将requests软件包安装到项目的根文件夹中

各项命名如下:

  • zip文件:lambda_function.zip
  • py文件:lambda_function.py
  • 处理方法:lambda_handler(event, context)
  • 在“webconfig: lambda_function.lambda_handler”中定义处理程序

最终要运行的文件如下:

import requests
import json


def lambda_handler(event, context):
    url = 'xxx.elasticbeanstalk.com/users/login'
    headers = {"content-type": "application/json", "Authorization": "Basic Zxxxxxxxxx3NjxxZxxxxzcw==" }
    response = requests.put(url, headers=headers, verify=False)
    return 'hello lambda_handler'

我很高兴能得到任何形式的帮助。我已经花费了数小时来解决这个问题。


2
在你的问题中,pip install 命令中 -t 选项的位置是不正确的 - 必须是 pip install requests -t PATH_TO_ROOT_FOLDER。你只是打错了吗,还是真的是这样运行的? - Leon
@Leon:好的,我刚刚查看了历史记录,我就像你在这里提到的那样做了。 :) 所以那不是问题的原因。 - codepleb
你在本地使用的Python版本是什么? - Leon
你看过 http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html 上的指南了吗? - Klaus D.
您的zip文件内容是否表明已正确添加了“requests”包? - Leon
显示剩余3条评论
9个回答

234

编辑:在2019年10月21日Botocore移除了requests的版本:https://github.com/boto/botocore/pull/1829.

编辑2:(2020年3月10日)Lambda服务捆绑AWS SDK中请求模块的弃用日期现在是2021年1月30日。https://aws.amazon.com/blogs/compute/upcoming-changes-to-the-python-sdk-in-aws-lambda/

编辑3:(2022年11月22日)AWS取消了弃用,因此您可以像下面描述的那样继续使用请求模块。AWS博客

要使用requests模块,您只需从botocore.vendored中导入requests。例如:

from botocore.vendored import requests

def lambda_handler(event, context):
   response = requests.get("https://httpbin.org/get", timeout=10)
   print(response.json())

您可以查看此代码片段来了解更多可直接在AWS Lambda中导入的模块。


24
这些是否会在以后的版本中消失是个问题吗?“尽管这些打包依赖项仍包含在botocore软件包中,但不应使用它们,因为它们将来会被移除。” https://botocore.amazonaws.com/v1/documentation/api/latest/index.html#upgrading-to-1-11-0 - Joshka
5
我不会再使用这种方法。botocore 的官方仓库上有一个警告,表示将来会删除 botocore.vendored requests。 - cvb
2
@MichaelBrant,你需要将requests库作为函数的一部分上传。https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html - Sathed
38
一则注释 - 这似乎不再起作用了。 AttributeError: module 'botocore.vendored.requests' has no attribute 'get' - Penumbra
4
对的,这篇博客说:“Python 3.8及更高版本的Lambda运行时不包括'requests'模块。” - Molossus
显示剩余6条评论

64

如果你在 AWS Lambda 上使用 Python,并且需要使用 requests,最好使用 urllib3,它目前在 AWS Lambda 上得到支持,你可以直接导入它,查看 urllib3 网站上的示例。

import urllib3

http = urllib3.PoolManager()
r = http.request('GET', 'http://httpbin.org/robots.txt')

r.data
# b'User-agent: *\nDisallow: /deny\n'
r.status
# 200

2
这是最好的答案。 - CLAbeel

25

我终于解决了问题:我的zip文件中的结构已经破损。重要的是,Python脚本和打包的依赖项(作为文件夹)必须位于zip文件的根目录中。这解决了我的问题。

如果你在尝试和失败几个小时后发现如此简单的错误,那会让人有点沮丧。


好的,这里没有任何进展,在你的代码中,你只是返回了“hello lambda_helper”,我想要返回整个从API Get获取到的JSON响应...如果你不知道也没关系,我可以提一个新问题。 - kafka
我返回状态码。但是,我对Python不是很熟悉。仅仅足够编写那个脚本。 - codepleb
请提供更多细节。 - softmarshmallow
抱歉,各位,这个问题太久远了,我无法再给出可靠的答案。我当时正在开发的那个项目早已不复存在。打包依赖项意味着将依赖项作为文件夹打包,通常在根文件夹中,但是很遗憾,我无法再提供更多信息了。 - codepleb
有没有不使用压缩和供应商模块的方法? - Tula
显示剩余4条评论

24

我相信您在Lambda控制台上有lambda_function.py。您需要先创建Lambda函数部署包,然后使用控制台上传包。

  • 您需要在本地系统上创建一个目录,例如project-dir
  • project-dir中创建lambda_function.py,将lambda控制台上的lambda_function.py内容复制并粘贴到project-dir/lambda_function.py
  • pip install requests -t /path/to/project-dir
  • project-dir目录的内容压缩成zip文件,这就是您的部署包(请压缩目录内容,而不是目录本身)

进入Lambda控制台,在代码输入类型中选择上传zip文件,然后上传您的部署包。导入requests应该可以正常工作,没有任何错误。


2
你可以在包含lambda_function.py的目录中使用pip install requests -t .(-t后面有一个点)而不是输入完整的项目目录路径。(来自qarly_blue的答案)。奖励:在Windows上也适用。 - Hansang

13

大多数评论在某种程度上是正确的,但对于AWS初学者来说并不足够信息丰富。以下是我长篇简述所需要做的内容,以访问 requests 功能:

1. 创建 AWS Lambda 函数的根目录
% mkdir lambda-function
2. 进入创建的根目录
% cd lambda-function
3. 为AWS Lambda创建入口Python文件。
% vi lambda_function.py
4. 将代码粘贴到lambda_function.py中
import requests
def lambda_handler(event, context):   
    response = requests.get("https://www.test.com/")
    print(response.text)
    return response.text 
5. 安装 requests 库。注意:已创建 package 文件夹。
% pip install --target ./package requests
6. 进入包内
% cd package
7. 压缩包
zip -r ../deployment-package.zip .
8. 进入上级文件夹
% cd ..
9. 压缩部署包和Lambda函数文件
% zip -g deployment-package.zip lambda_function.py
  1. 在 AWS Lambda 函数中,点击 "从此处上传",然后选择".zip 文件"。 浏览到您的 zip 包 zip 文件: deployment-package.zip。
  2. 上传后所有文件都会在 AWS Lambda 函数中。

enter image description here


9
使用这个命令下载文件夹包。
pip install requests -t .

在您的本地机器上运行这个命令,然后压缩您的工作目录,最后上传到AWS。

3
不要认为这适用于AWS Lambda。 - Jason Wheeler
这个答案与Pramod Munemanik的下面的答案一起,目前是最好的答案。 - Hansang

8

Python 3.8 Windows 10

下面我们将按照(https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-create)中的步骤来创建lambda特定的文件夹结构如下: https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-create

  1. 在桌面上新建一个名为“python”的文件夹,在cmd终端中输入cd desktop进入文件夹。
  2. 输入命令pip install --target python requests。
  3. 右键单击python文件夹并压缩,将zip重命名为“requests.zip”,现在在zip文件中应该可以看到python文件夹。
  4. 进入aws控制台>lambda>layers>create layer =>输入名称和上传requests.zip。
  5. 进入aws控制台>functions>create function =>在设计者选项卡中选择图层然后点击“add layers”选择custom layers并选择您的图层。
  6. 通过点击设计者选项卡中的lambda符号返回函数屏幕。现在您可以再次看到“function code”。点击lambda_function.py

现在您可以像这样导入requests:

import json
import requests

def lambda_handler(event, context):
    # TODO implement
    response = requests.get('your_URL')
    return {
        'statusCode': 200,
        'body': json.dumps(response.json())
    }

1
  1. 从AWS Lambda控制台复制lambda_function中的内容,并将其粘贴到一个新的Python脚本中,另存为lambda_function.py

  2. 创建一个新文件夹(我命名为package),并通过在终端运行以下代码将requests模块保存在其中:pip install -t package requests

  3. lambda_function.py移动到文件夹(package)中。

  4. 进入该文件夹并选择所有内容,然后将它们压缩成zip格式。

  5. 返回AWS Lambda控制台。选择函数,在“函数代码”部分下,单击右侧的“操作”,然后选择上传.zip文件

  6. 上传文件夹,lambda_function应该会自动上传。

  7. 运行并享受。


这只是 这个2017年的回答 改述了一下。 - Andras Deak -- Слава Україні

0

通过指定此 ARN (ap-south-1) 将层添加到您的 Lambda 函数

 arn:aws:lambda:ap-south-1:770693421928:layer:Klayers-p38-requests-html:10

4
这个 ARN 是从哪里来的?向 Lambda 添加非官方代码似乎是一种危险的行为。 - Ryan Amos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接