Reputation: 10571
I need to do a rest-call within a python script, that runs once per day. I can't pack the "requests" package into my python-package using the AWS Lambdas. I get the error: "Unable to import module 'lambda_function': No module named lambda_function"
I broke it down to the hello_world predefined script. I can pack it into a zip and upload it. Everything works. As soon as I put "import requests" into the file, I get this error.
Here is what I already did:
The naming of everything looks like this:
The file I want to run in the end looks like this:
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'
I'm glad for ANY kind of help. I already used multiple hours on this issue.
Upvotes: 107
Views: 187565
Reputation: 1853
Without installing any modules, Diego Tejada's answer was perfect.
All I did additionally is make wrapper functions for to use as is:
def request(method, url, payload=None):
import urllib3
http = urllib3.PoolManager()
args = { "method": method,
"url": url }
if payload is not None:
args.update({ "body": json.dumps(payload),
"headers": {"Content-Type": "application/json"} })
response = http.request(**args)
return response
def get(url):
return request('GET', url)
def post(url, payload):
return request('POST', url, payload)
No need to import anything at the top, just add these lines, and you can use get and post function anywhere in your lambda script. For put, delete or non-json body, edit the snippet accordingly (or just give it to ChatGPT to do - it excels at no brainers like this).
Upvotes: 0
Reputation: 1
Add a layer to your lambda function by specifying this arn (ap-south-1)
arn:aws:lambda:ap-south-1:770693421928:layer:Klayers-p38-requests-html:10
Upvotes: 0
Reputation: 2693
EDIT: On Oct-21-2019 Botocore removed the vendored version of requests: https://github.com/boto/botocore/pull/1829.
EDIT 2: (March 10, 2020): The deprecation date for the Lambda service to bundle the requests module in the AWS SDK is now January 30, 2021. https://aws.amazon.com/blogs/compute/upcoming-changes-to-the-python-sdk-in-aws-lambda/
EDIT 3: (Nov 22, 2022): AWS cancelled the deprecation so you can continue to use requests as described below. AWS Blog
To use requests module, you can simply import requests
from botocore.vendored
. For example:
from botocore.vendored import requests
def lambda_handler(event, context):
response = requests.get("https://httpbin.org/get", timeout=10)
print(response.json())
you can see this gist to know more modules that can be imported directly in AWS lambda.
Upvotes: 243
Reputation: 16549
Most of the comments somehow correct, but not enough informative for AWS beginners. Here is my long resume what needs to be done for accessing requests functionality:
% mkdir lambda-function
% cd lambda-function
% vi lambda_function.py
import requests
def lambda_handler(event, context):
response = requests.get("https://www.test.com/")
print(response.text)
return response.text
% pip install --target ./package requests
% cd package
zip -r ../deployment-package.zip .
% cd ..
% zip -g deployment-package.zip lambda_function.py
Upvotes: 17
Reputation: 1060
python 3.8 windows 10
lambda is looking for a specific folder structure and we are going to recreate in this manner in the steps below (https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-create):
Now you can import requests like this:
import json
import requests
def lambda_handler(event, context):
# TODO implement
response = requests.get('your_URL')
return {
'statusCode': 200,
'body': json.dumps(response.json())
}
Upvotes: 8
Reputation: 378
Copy whatever you have in the lambda_function
fron AWS lambda console and paste it in a new python script and save it as lambda_function.py
.
Make a new folder (I name it as package) and save requests
module in it by running the following code in terminal: pip install -t package requests
Move lambda_function.py
into the folder (package).
Go to the folder and select all content and zip them.
Go back to the AWS Lambda console. select the function and under the Function code section, click on 'Action' (on the right side) and select Upload a .zip file
.
Upload the folder. lambda_function should be uploaded automatically.
Run and Enjoy.
Upvotes: 1
Reputation: 1171
If you're working with Python on AWS Lambda, and need to use requests, you better use urllib3, it is currently supported on AWS Lambda and you can import it directly, check the example on urllib3 site.
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
Upvotes: 76
Reputation: 420
With this command download the folder package
pip install requests -t .
Run this command on your local machine, then zip your working directory, then upload to aws.
Upvotes: 11
Reputation: 281
I believe you have lambda_function.py
on the Lambda console. You need to first create the Lambda function deployment package, and then use the console to upload the package.
project-dir
on your system (locally)lambda_function.py
in project-dir
, copy the content of lambda_function.py
from lambda console and paste it in project-dir/lambda_function.py
pip install requests -t /path/to/project-dir
project-dir
directory, which is your deployment package (Zip the directory content, not the directory)Go to the Lambda console, select upload zip file in code entry type and upload your deployment package. Import requests should work without any error.
Upvotes: 24
Reputation: 10571
I finally solved the problem: The structure in my zip file was broken. It is important that the python script and the packed dependencies (as folders) are in the root of the zip file. This solved my problem.
It's a bit depressing if you find such easy errors after hours of try and failure.
Upvotes: 26