Alexa Skill with Lambda function in Python and DynamoDB

Overview

This post will show how to build a simple Alexa skill in Python, and how the use of the browser based Sigma IDE will help in the development of Lambda functions, especially in deploying code changes to live AWS in about 3 seconds, and allowing drag-and-drop code generation for AWS resource access, such as DynamoDB. The Sigma IDE also supports NodeJS and was the first IDE to allow NodeJS Lambda functions to be live debugged during execution on AWS.

Getting Started

The following outlines the interaction of the Alexa VUI and the AWS Lambda function we will develop, and how the Lambda function will lookup a Dynamo DB table in the final stage. We assume that you already have an Amazon Alexa developer account, an AWS account, and a free Sigma IDE account. You will also need a Git repository such as GitHub or BitBucket to save your code. For those who would rather view the full video of this, you can proceed here.

Creating the VUI

1. First login to the Alexa developer console and create a new skill. Lets name it the ChineseAnimal

2. Choose the Start from scratch template in the next step 

3. Specify the invocation name as “chinese animal” as this needs to be two words. This is what you will use to ask Alexa to start this skill.

4. Next add a new Intent from the left hand pane

and name it the “ChineseAnimalIntent”. This intent name must match the name specified at the intent handler in your Lambda function later.

5. Add the utterances for the custom intent. Lets add “what is my chinese animal for the year {year}” and “what is the chinese animal for the year {year}”. The “{year}” is called a slot – which is like a variable, and would be available to your Lambda function for the backend code to read. Finally go to the Intent Slots section below, and select the “{year}” to be of the slot type “AMAZON.FOUR_DIGIT_NUMBER” so that the user will be able to specify 2012, or 2010 etc.

6. Save the model and Build it, so that the Alexa AI magic can happen. Then go to Endpoints, and select AWS Lambda ARN as the Endpoint type, and copy the Skill ID to your clipboard.

Creating the Lambda function

1. Go to the https://sigma.slappforge.com to open your Sigma IDE with your favorite browser, and create a new project, selecting your primary development language as Python.

2.  The Sigma IDE will open with a default Lambda function in Python, and you can go ahead and write any code and run it without having to compile or deploy.. yes it runs on your AWS account, and you do not need to use a CLI or edit configuration files at all. Next, drag the Alexa Skill from the left-hand side pane of AWS resources, and drag it to the Lambda handler function definition line and drop it.

In the window that opens to the right, paste the Alexa Skill ID that you copied to the clipboard. Finally, select Inject.

 

Alexa skill trigger

Your trigger should be set for the Lambda function, and the icon would turn green as follows

 

3. Go to the Dependencies, and add the dependency for “ask_sdk_core” version “1.13.0”

4. Then type the following code into your function. You can find the code here on GitHub. Basically your code has a few import statements and has three classes like the following, where the various handlers are defined.

The above is the handler for the custom intent we defined called the “ChineseAnimalIntent” and returns so for the can_handle() function. You should refer to the Alexa SDK and other documentation for a complete overview of the SDK and code development. In addition the above, we also define the “LaunchRequest” handler which will get triggered when you say “Alexa open chinese animal” and also the error handler “CatchAllExceptionHandler” which will get invoked on any unexpected exceptions. The handle() method defines the output returned to Alexa, specifically the text we return to the speak() call. Right now the handler will make Alexa say “My custom intent handler”.

Finally, you complete the code by creating a SkillBuilder instance, and assigning the various handlers you defined above. The handler method of the Lambda function will invoke the handler generated by the SkillBuilder

5. You can now Deploy the project, and the Sigma IDE will prompt you to save the code to your Git repository and will perform the full AWS deployment, including the creation of any roles, the minimum security policy generation based on resourced used and accessed, etc.

6. Once the deployment completes, the ARN of the Lambda function is shown – copy this to the clipboard.

Go back to the Endpoint section of the Alexa skill definition and paste the ARN and save it

7. Go to Test on the Alexa developer console and change the mode to “Development” for this skill

Now you can invoke the Alexa skill by pressing the microphone and saying “open chinese animal”. The “LaunchHandler” will execute and return the response as follows. If you already have an Alexa device linked to your developer account, you can invoke the same from the device by saying “Alexa open chinese animal”

alexa skill template

Code changes take effect in approximately 3 seconds!

After the first deployment through the Sigma IDE, you can use the “Quick Deploy” feature to push code only (i.e. not an addition of a new AWS resource, etc) changes to the live AWS environment in approximately 3 seconds or less! Try the below code change for the LaunchHandler and invoke it again from the Alexa Test console or device to see the change in seconds

You can also change the ChineseAnimalIntent handler as follows to return a hard coded response as an example, and check the output

Now test via the Test console or an actual Alexa device

Drag-and-Drop the code to access DynamoDB

Finally, we will drag DynamoDB from the palette to the custom intent handler and drop it.

A window will open on the right-hand side, which will allow you to either define a new DynamoDB table or use an existing DDB table. In my case, I already have a table called ChineseAnimal with three attributes like the following.

Thus, I will select this existing table, and select the operation as GetDocument and pass the “@{year}” as a variable for the partition key.

Pressing Inject will generate the required code for me, add the dependencies to the project automatically, and also update the security to allow the function to just read this table – all without having to write any error-prone configuration files by hand or opening any AWS consoles!

I can click on the DDB icon to the left of the line numbers to update this code anytime if needed. And you were spared the effort to search for sample code, cut and paste someone else’s code, and changing it to suit your code all in one drag-and-drop stroke. You can further customize the code now, and we will update the code to return the results retrieved from the DDB table as shown above.

Since we added a new AWS resource to the Lambda function, we will need to perform a “Full deployment” one more time. However, any other code changes, later on, will just take 3 seconds as usual!

Now you can invoke the Alexa skill with the DDB call from the Test console or an actual device as follows

Closing Remarks

You can find the full Github project at https://github.com/asankhaperera/chineseanimal

In a future post, I will show the same function being implemented with NodeJS, and show you how you can step through and debug the function as it executes live on AWS

And here is the full recording of this Alexa skill development for your reference