Serverless: Upgrading Lambda function from Python 2.7 to Python 3.8

Upgrading AWS Lambda Function code from Python 2.7 to Python 3.8

This story takes the reader through the process of upgrading AWS Lambda Python code from Python 2.7 to Python 3.8. There are a couple of ways to accomplish this, but in this story I will take your through deploying a new Lambda Function and changing the EventBridge trigger to call your new Lambda Function

Background

Our existing Lambda function is from an Elastic Block Storage (EBS) snapshot scheduler which was an existing deployment provided by AWS. This python code was deployed with Python 2.7

Create a New Lambda Function

Our first option that we will explore is deploying a new Lambda function and modifying the existing code to be supported with Python 3.8. One of the biggest changes related to Python code with the upgrade from Python 2 to Python 3 was the change in the “print” statement. The “print” statement is commonly used for debugging and logging so you will commonly see this function in most python code.

The screen shot below is an example of the existing Lambda function definition. You will notice that the code is deployed as a “Zip” package type.

In the screen shot below of the Python Code, you notice the statement “print e” and there are numerous print statements in the code that will need to be altered

Step 1: Backup your existing function code

As a precaution with everything we do in the IT space it is good to start with a backup. On the top right corner of the screen there is an “Action” drop down list. Press the “Action” title and select “Export function”

Then we will select “Download deployment package”. This will down a Zip file with the original deployment package an any code changes that have occurred. Save this file somewhere were you can find it in the future, incase there are any issues.

Step 2: Create a new version of your code

Navigate to Lambda Functions. On the top of the screen you will see your existing functions. We will create a new function with the “Create function” orange button on the top right.

On the create screen we will give a new “Function name”, and select the “Runtime” of “Python 3.8” and in this case we will use the existing role from our previous Lambda function as we are going to be duplicating that code. Then press the “Create function” on the both

Next we will need to import your code as a Zip file or if you are using code that does not require supporting libraries you can add your code directly into the editor. While you are converting your code you will need to make sure you convert all of the print statements to the Python 3 version of a print.

Python 2 print statement

Python 3 print statement

After you have changed your lambda_function.py code to incorporate all of the Python 3 changes you will need to upload a Zip of the code. If you need help creating a zip file for python libraries that are not part of the AWS Lambda default footprint you can follow the following article

Also don’t forget to edit the basic settings if your code is taking a while to execute and you get a timeout message. The default for Lambda is 3 seconds

Step 3: Test your Code

We will then test the Lambda function by pressing the “Test” button on your “Code” screen for the Lambda function

Name your test, and provide any JSON data objects that you normally test your code with. This will give you an execution results tab that you can debug your code from.

Step 4: Edit your existing EventBridge to call your new Lambda Code

Navigate to your original Lambda function and click on the trigger, in our case the trigger is an “Amazon EventBridge”. Then click on the “Edit Rule” action

Then scroll down on the screen to the section labeled “Select targets” and select the drop down next to “Function”. Here we will select the Lambda function that we created in Step 2

Hope this helped migrate your Lambda function to Python 3 by creating a new Lambda function and changing the trigger to call your new Lambda function.

Helpful Python2 to Python3 Conversion Notes

Problem: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.

Solution: use the .encode() at the end of the data

Problem: ‘dict’ object has no attribute ‘iteritems’

Solution: use the dict.items() instead of the dict.iteritems()

Hope you enjoy the story — Jason DeLano