--- title: "Python for AWS Lambda Functions: A Beginner's Guide" date: "2022-03-24" categories: - "python" coverImage: "aws-lambda.jpg" --- # Python for AWS Lambda Functions: A Beginner's Guide Other than data science and machine learning, I believe the one use case driving the popularity of Python in recent years has been its suitability for serverless cloud computing. Especially for junior developers interested in a role as a Software Developer or DevOps Engineer, I would argue that learning about serverless computing represents a huge potential opportunity if you enjoy working in Python. On the cloud provider that leads the rest in market share, Amazon Web Services (AWS), serverless computing takes the form of AWS Lambda functions. Developers and DevOps Engineers call on Lambda functions to provide functionality that doesn't require a long-running process. For example, they can serve as API endpoints. Even more importantly, AWS Lambda functions serve as "glue functions" Companies doing business on AWS quickly learn that AWS Lambda functions are the most common mechanism to enable customizing AWS Services. We'll start slowly by listing and defining some basic terms in this article. Once we understand the territory, we can start locally building and running some simple lambda functions. At first, we won't even need an AWS account, but before long, we'll want to sign up for one if we don't have one already. After all, understanding a few simple ways to deploy our functions to AWS is part of working with Lambda functions. ## Some Basic Definitions Before we begin working with serverless and AWS Lambda functions, let's make sure we understand some basics. The first term that may strike you as unusual is "serverless" -- how can that be? Of course, if we dig deep enough, no computer program is really "serverless." Your code has to run _somewhere_. Marketing-speak like this has led to lots of successful memes and jokes. For example: "There is no cloud -- it's just someone else's computer." For serverless, we might coin an equivalent joke: "Yes, there's a server; it's just not yours." When we talk about functions that are "serverless," we're talking about a service provided by someone like AWS where: - We, the customer, don't have to think about, administer, patch, or otherwise care about the server. AWS handles it for us. - We're [billed](https://aws.amazon.com/lambda/pricing/) only for what we use, at very small increments of time + memory configured. Moreover, AWS provides generous free tier pricing, so unless you're going to go several orders of magnitude beyond what we'll do in this article, you won't pay anything. So again -- serverless doesn't mean that the server doesn't exist. It means that you, as the user, don't need to think about it. The second term we should be clear about is "Lambda function." We don't have to spend too much time on this, except to point out that AWS Lambda functions have nothing to do with Python lambda functions. Python lambda functions are anonymous inline functions declared without the def keyword. Often these are used as inputs to other functions, for example: ```python list(map(lambda x: x * 2, [1,2,3])) ``` Output: ```bash [2, 4, 6] ``` In the AWS case, "Lambda functions" are a brand name for AWS's implementation of a mechanism to run functions in a serverless way. In my experience, most developers write these in Python, but you could also write them in other languages. Currently, Lambda functions can be written in Java, Go, PowerShell, Node.js, C#, Python, or Ruby. AWS Lambda functions are not anonymous functions. As we'll see in the next section, they are simple functions written in the target language with specific parameters. ## Creating a Lambda Function (Spoiler: It's Just a Function) Before we get into the tools needed to deploy our Lambda function to AWS, let's be bold. Let's plow ahead into Lambda functions as if we won't eventually need an AWS account or a command-line tool or anything else. (Because at this stage, we don't). Open up a file in your favorite text editor, and create a file named lambda\_function.py. Enter this code: ```python # lambda_function.py """lambda function demo""" import json def lambda_handler(event, context): """lambda_handler is a hello-world lambda function""" print('Hello, Lambda!') return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') } if __name__ == "__main__": """Demonstrate that this is just a function we can run locally""" result = lambda_handler(None, None) print(result) ``` Believe it or not, you just wrote your first AWS Lambda function. Now having done that, let's go ahead and run it. Make-believe you're a cloud, go to the console and type: ```bash python3 lambda_function.py ``` Output: ```bash Hello, Lambda! {'statusCode': 200, 'body': '"Hello from Lambda!"'} ``` So now you created an AWS lambda function, and you ran it. I promise you, that's what you did. Admittedly, we cut a few corners -- we didn't run it _**as**_ a Lambda function. We pretended to be a cloud, and then we ran it. So don't add "AWS Lambda Functions" to the skills section of your resume just yet. We should at least run it in AWS first. When we do publish this Lambda function using the AWS Console, you'll see that it's very similar to the default starter Lambda that AWS will create for you there. ## Getting An AWS Account and Configuring the AWS CLI You can skip this section if you already have an AWS account and have your AWS command-line tool (the CLI) configured. However, this is a prerequisite for using AWS, so we'll briefly highlight what's involved. Here's the site to sign up for an AWS account: https://aws.amazon.com. I will let you walk through the process yourself, as signing up for an AWS account requires a credit card. They may hold $1.00 temporarily for 3-5 days "to verify your identity." You shouldn't be charged for anything you do as part of this demo other than that. AWS provides a free tier for Lambda, under which you get a relatively liberal use of the AWS Lambda service every month for free before it costs anything. You may want to delete the S3 bucket we create because that may cost you a whopping 2.3 cents per month -- other than that, there should be no charge for the whole tutorial. Once you have an AWS account up and running, you'll likely want to get the AWS Command Line Interface Tool (The "AWS CLI"). AWS has good documentation for how to install it and configure it. You'll need to have done this to work through the section on Publishing a Lambda Function Using the AWS CLI. Before we work through that, let's show how to get it to work "the easy way," using the AWS Console (i.e., the website). ## Publishing a Lambda Function from the AWS Console Now that we have an AWS account, the easiest -- though least automated -- way to install a lambda function is through the AWS console at [aws.amazon.com](https://aws.amazon.com/). Once you've logged in, the easiest way to navigate to any AWS service is via the search bar on the top. Here we've searched for Lambda: ![](/images/python-and-aws-lambda-functions/services_search_lambda-1024x223.png) Clicking on Lambda will bring us to a page where we can create a function. The view may vary if the account is brand new, but you should see a "Create Function" button on the upper right-hand side. Clicking Create Function will bring you to a page where you can easily create a simple Lambda function from scratch. We select "Author from scratch" in the top row (it should be the default). We give our function a name, and under Runtime, select the latest Python version. We can leave architecture at the default x86\_64. If we do this through the console, AWS will automatically set up an IAM role, or set of permissions, for our Lambda function to use. That should be the default, so we leave it as it is. ![](/images/python-and-aws-lambda-functions/create_lambda_small-1024x466.jpg) Scroll down to the bottom of the page and click Create Function. This will bring you to a page that shows a function that looks like a slightly slimmed-down version of the function we wrote above: ```python import json def lambda_handler(event, context): # TODO implement return { 'statusCode': 200, 'body': json.dumps('Hello from Lambda!') } ``` Let's look at what else we have available in this view. As we can see in the image below, the top row gives us several options. Among the most useful of these is the Configuration tab, which lets you configure a lambda much more thoroughly than we've done here, including setting environment variables. We also can view Aliases or Versions. At present, we have only one version deployed. If we modify this function and click Deploy on this page, we'll can then go to the Versions tab if we want to Snapshot the new function as a new version. ![](/images/python-and-aws-lambda-functions/image-1.png) One feature we can use over and over again, especially as our functions start having more to do, is to test them. From the view above, clicking Test will allow us to create a test event. This will look as shown below. Since we're not processing the event JSON for now, we can leave that field at the default, and enter a name for the event in the EventName field, as shown below: ![](/images/python-and-aws-lambda-functions/image-3-693x1024.png) This will bring us back to the Code source page, and from there, we can click the dropdown next to the "Test" button to test the function, selecting the event we just saved, then click Test. We'll see the functions response and the logs for the run, as shown below: ![](/images/python-and-aws-lambda-functions/image-4-1024x399.png) To get more familiar with this interface, you might try pasting the code we created above in the section "Creating a Lambda Function (Spoiler: It's Just a Function)". Click deploy to deploy a new version and Test again to test it out. ## Publishing a Lambda Function Using the AWS CLI Once we have the AWS CLI installed and configured for our account, we can also upload our Python Lambda function to AWS" using the CLI. This is slightly more involved than doing it from the AWS console, but it helps us understand some other dependencies. Also, it gives you the background you would need to code it in a CI/CD platform at some point if you needed to do that. The first thing we need to do is prepare a "build package," consisting of our handler function and any dependencies. At this point, we don't have any dependencies, so let's zip up our build file: ```bash zip lambda.zip lambda_function.py ``` Next, we will create an IAM role for the Lambda function to run in. IAM roles are sets of permissions we can apply to resources such as functions or users. Let's create a role with basic permissions. The following code should appear all on one line when copied. ```bash aws iam create-role --role-name lambda-ex --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}' ``` The output will vary but look something like this. We'll copy the value for "Arn" to the clipboard and use it in the next step. ```bash aws create-function{ "Role": { "Path": "/", "RoleName": "lambda-ex", "RoleId": "AROAVJIRR95YUJTABCD", "Arn": "arn:aws:iam::36349901212:role/lambda-ex", "CreateDate": "2022-03-15T19:18:33+00:00", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } } } ``` OK, with that, we're ready to create our Lambda function. Let's look at the whole command first; then, we can discuss the various parts. (One important caveat is that the function name we use below should differ from the function name we used when we deployed a function using the console). ```bash aws lambda create-function \ --function-name hello-lambda \ --runtime python3.9 \ --zip-file fileb://./lambda.zip \ --role \ --handler lambda_function.lambda_handler ``` AWS CLI commands generally follow the format of "`aws