We’ve previously covered AWS Lambda using Java. Today, we’ll take a look at Python.

If you’re unfamiliar with AWS Lambda, it’s what we call a Function-as-a-Service offering from Amazon. A FaaS system hides all the infrastructure details from you, even more so than Platform-as-a-Service (PaaS). Whenever you need to scale a PaaS application, you typically add extra server processes. In a FaaS system, you just add more executions.

That’s all quite abstract, isn’t it? For you as a developer, it just means you write code that has a single entry point, and you return a result. This is the “function” in “Function-as-a-Service.” You can of course have multiple branches in a single function, though it’s advised to avoid too much complexity.

After you’ve uploaded your code, you can configure different “triggers” to execute your function. Typically, you might think about an external call to some public API. But you can also configure triggers from certain events in other parts of the AWS ecosystem. Some examples are:

  • a file has been uploaded to S3
  • a cron job
  • a message has been published to an SNS topic

Whenever concurrent executions are required, AWS will just create new instances of your function and execute those. It can scale quite transparently.

Though this can come with unexpected costs. You pay for execution time. This is nice, because you only pay for what you use. But if you use a very high amount, you’ll pay accordingly.

For our tests, this won’t be an issue. You can use many different AWS services for free for the first 12 months of your account. So if you don’t have an account yet, go ahead and set one up.

Setting Up Our Project

We need an application to invoke first. To make our lives easier, we’ll use the excellent Serverless framework. This framework will make it easy for us to configure, package, deploy and debug our Lambda function. It also works for other cloud providers than AWS.

To install Serverless, make sure you have Node.js installed and run this command at the command-line:

npm i -g serverless

Then initialize your project by running:

serverless

You’ll have to answer some simple questions and then you can you’ll have a folder with two files that are of importance:

  • handler.py
  • serverless.yml

The handler.py file is where our code goes. The serverless.yml file is where we configure our Lambda function and everything else in AWS that relates to our function.

Implementing a Function

The Serverless framework will have created some boilerplate code for us. The important part is that there is a single function with the following signature:

def hello(event, context):
    # return an object with a statusCode and body

There is an event and a context parameter. The event contains the body that was passed to our Lambda function, as well as other possible details like HTTP headers. It really depends on how your Lambda function is invoked. The context has interesting information about the invocation and environment. You can read about it in the official documentation.

Let’s change the code to something more realistic. Let’s validate an email address:

import json
import re


def validate(event, context):
    event_body = json.loads(event['body'])
    email_regex = re.compile('^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$')
    matches = email_regex.match(event_body['email']) != None

    response = {
        'statusCode': 200,
        'body': json.dumps({ 'result': matches })
    }

    return response

Incidentally, validating email addresses is hard and there are many regular expression out there. This particular regex is taken from emailregex.com where they claim it works in 99.99% of the cases.

As you can see, we’re parsing the body from our event (it will be JSON) and than checking if it’s an email address. At the end we return a dict with a statusCode and body.

Because we’ve also changed our function name, we need to make some changes in the serverless.yml file as well.

Configuring Our Lambda Function

If you look at the serverless.yml file, you’ll see many helpful comments. But if you take that all away, you’ll see there’s not much to it:

service: email-validator

provider:
  name: aws
  runtime: python3.8

functions:
  main:
    handler: handler.validate

Here we can give our service a name, specify on which runtime to run, give our functions a name and specify which Python function to execute.

Let’s change it to:

service: email-validator

provider:
  name: aws
  runtime: python3.8

functions:
  main:
    handler: handler.validate

We’re now ready to test our function.

Testing Locally

Without the Serverless framework, it’s not always easy to test a Lambda function locally. This is because you might need to provide the event and context parameters. Serverless can do all this for you.

Just run this command to invoke the function:

serverless invoke local --data '{"body": "{\"email\": \"test@example.com\"}"}' --function main

You’ll see the result:

{
    "statusCode": 200,
    "body": "{\"result\": true}"
}

Try it out with an invalid email address and you’ll see the result is false.

Now that we’re happy with our code, let’s get it running on AWS.

Deploying to AWS

First we need to give Serverless access to our AWS account. In the AWS Console (the web UI of AWS), go to Identity and Access Management (IAM) and select the Users section. Click on the Add user button at the top of the page to create a new user:

You’ll have to give the user a name and Programmatic access:

Proceed to the next page and be sure to give your user access to the following AWS services:

  • Lambda
  • IAM
  • S3
  • CloudFormation

Your permissions could look like this:

Then continue and confirm to create your user. You’ll see an overview where you can see the access key and the secret:

We can now configure serverless to use these credentials:

serverless config credentials --provider aws --key AKIA52XT4ILHYF5UR54E --secret xxxxxxxxx

Now all you need to do is run:

serverless deploy

Depending on your location, you may have to add –region eu-west-1 (or another region) to that.

Our Lambda function is now up in the cloud, but it can’t be triggered yet. You can test it from inside the AWS Console, and you can configure all kinds of real events to trigger your function. In our case, let’s expose it via the API Gateway that AWS offers.

Invoking Your Lambda Function

Before we do this, we’ll need to go back to the IAM section in the AWS Console and give our user access to AmazonAPIGatewayAdministrator (to create the API Gateway) and AmazonAPIGatewayInvokeFullAccess (to invoke the endpoint).

Now that we have access, we can add a trigger to our serverless.yml:

service: email-validator

provider:
  name: aws
  runtime: python3.8

functions:
  main:
    handler: handler.validate
    events:
      - http: POST /email/validate

See those last two lines? That means, we’ll create an API Gateway with a single endpoint. Whenever a HTTP call is made to that endpoint, AWS will route it through to our Lambda function.

After deploying again, we can go to the API Gateway section in the AWS Console, select our new API Gateway, and select Dashboard in the left menu. There you’ll see the public URL that you can use to invoke the Lambda function:

You can now make a request using a tool like Postman for example:

When you do, you will have to authorize yourself. If you’re using Postman, you can select the “AWS Signature” option in the Authorization tab. There, you can enter the key and secret that was created with your user. You might also have to specify the AWS region (“eu-west-1” in my case).

Building an Application

You’ve now set up a simple Lambda function using Python. We used the Serverless framework because it makes our life easier and allows you to adhere to the infrastructure as code principle: everything we configured can be put in source control.

We’ve made our function accessible via HTTP request, but what we really did, is add a trigger that invokes the function. This trigger happens to be linked to the API Gateway service. But you could also trigger your Lambda function by one of the many other services that AWS offers. In case you do use API Gateway, you’ll probably want to look into custom domain names and other authorization mechanisms.

There so much more you can do with Lambda functions. Indeed, there are entire suites of applications that run on AWS Lambda and its sibling services. With this article, you’ll be off to a good start.

This post was written by Peter Morlion. Peter is a passionate programmer that helps people and companies improve the quality of their code, especially in legacy codebases. He firmly believes that industry best practices are invaluable when working towards this goal, and his specialties include TDD, DI, and SOLID principles.

Leave a Reply

Your email address will not be published. Required fields are marked *

THE TOP LIST OF BLOG

SUBSCRIBE TO OUR BLOG

Jump in with your own data. Free for 30 days.

Free Trial