AWS Lambda triggered by catch-all Alexa Skill

For my most recent project, I wanted to have a way to control my RaspberryPi from my Amazon Echo. I already figured out a way to connect to my RaspberryPi from AWS in a secure way in my last post. Now it was time to play with the other end: writing an Alexa Skill. As a first step towards that direction, I wanted a catch-all Alexa skill that calls an AWS Lambda. This post outlines how I got an AWS Lambda triggered by catch-all Alexa Skill.

AWS Setup

The first thing needed to do this whole project is an AWS account. In order to create one, follow the instruction on the AWS Portal.

At the time of this writing, AWS Lambda has a free tier allowing 1,000,000 free requests per month and up to 3.2 million seconds of compute time per month. There is no reason why this should not be enough for this project. But do watch out: you can easily occur costs if you add other services.

Once you created your account, you will need to generate an access key for your user. It is a bad plan to create an access key for your root user. You should look into how to secure your AWS account but for the sake of this quick project, following this guide will give you what you need.

Alexa Developer Console Setup

In the Developer Console, you will create a new Skill. That new skill will use a custom model and backend resources that you will provision yourself. No need to select any template, we will be doing all the work ourselves.

The Alexa Skill

I won’t go over everything that needs to be done to configure the Skill. The most important parts I could find to achieve what I wanted were:

  1. Create a new Intent; in this Intent, add one slot of type AMAZON.SearchQuery
  2. In the ToolsAccounts Linking section, you will need to disable account linking (first option)

Every time you do changes, remember to hit the Build button. This will validate your setup. You can also go into the Certification section. This will allow you to run validations on your configuration and give pointers on how to fix issues.

The AWS Lambda

The next step is to create your AWS Lambda. In order to do so, simply go to the AWS Lambda home page and hit Create Function. We will be writing our function from scratch, using a Python 3.7 runtime.

The code we will be using for this lambda resides in this repository. It does not do much: it outputs any slots it could find to the logs of your lambda. But it can at least show that the linking worked correctly.

Deploying the code can be done directly through the Lambda UI or using the script in the above repository. Once deployed you can use the Test button directly in the Lambda UI in the AWS portal to trigger a run of the code. You will need to enter the content of the lambda_test.json file when asked for a test configuration.

Linking the Skill to the Lambda

In order to link everything, you will need two pieces of information:

  1. The ARN of the Lambda you created
    You can get this information by going to the AWS Portal and selecting your Lambda, the ARN will be at the top right
  2. Your Skill ID
    This information you can get from the Amazon Developer portal, by going into your skill and into the endpoint section

The linking needs to be done in both direction:

  1. In the Amazon Developer portal, in the endpoint section of your skill, you will need to enter the Lambda ARN into the default region field
  2. In the AWS portal, after selecting your Lambda, you will need to add a new trigger of type Alexa Skills Kit and enter the Skill ID of your skill

Testing Everything

There are multiple ways to test this setup:

  1. Testing using an Echo device
  2. Use the Amazon Alexa app on your smartphone
  3. Use the test UI in the Amazon Developer portal

I strongly suggest using the Amazon Developer portal since this removes the ambiguity of speech-to-text. In order to access this UI, simply go onto the Amazon Developer portal, select your skill and go into the Test section on top. There you will be able to enter text directly into the simulator.

Various related links

Book Review: Effective Python: 59 Specific Ways to Write Better Python

Lately, I’ve been reading Effective Python: 59 Specific Ways to Write Better Python. When I randomly selected this book, mostly based on its title, I had already beenEffective Python: 59 Specific Ways to Write Better Python working on an established Python project at work for a few months. Therefore I already had a bit of experience on good practices, do’s and don’ts. But coming from languages like C, C++, and Java, I had a bit of issue with the whole Pythonic Way of things.

The first chapter of this book talks about the language and the Pythonic Way of doing things. Since I had been working a few months on a Python project, this chapter was not that interesting to me. But I would have loved this kind of information when I first started working in Python. It covers small things like PEP8 style, slicing, list comprehension, generators, and various other language-level things.

The second chapter revolves around functions. A few basic concepts are presented, for example: how to document a function and how to write a generator. But a few more interesting are also covered: how closures interact with variable scopes, star arguments, and keyword arguments. But what was most interesting to me were all the details about the differences between Python 2 and Python 3 for all of these.

The third chapter covers the basis around classes and inheritance. To me, the one interesting part of this chapter was the examples using ABCs (Abstract Base Classes). It got me interested in the concept of metaclass in Python.

Luckily for me, chapter four covered metaclasses. For the first time since starting this book, I applied something I read from it at work: we expose plugins and callbacks to other teams and had no way of ensuring that they implement all these correctly; Now, using metaclasses we can ensure that they at least have the correct methods in their plugins. It’s not much, but it’s still a lot better than it used to be.

Chapter 5 could have been summarized in one sentence: never use threads for CPU-bound computation, only for I/O; use sub-processes for CPU-bound computation. This is something I had already learned while working at my job. One of my first tasks on my new team was to optimize one of our services. We basically moved a bunch of processing from background threads to the main thread, keeping the background threads for I/O only. This gained us a lot of processing power. Next thing we did was to reduce the number of threads in our process, we noticed that this also helped a lot the performance of the service. We moved these to a second process that now handles only I/O threads, lots of these, while the main process generates things to do.

Chapters 6 and 7 go about explaining a little about libraries and tools. Amongst other things, it explains about virtual environments, pip, functools and other little things like this. Again, I did not really learn anything here, to me these are needed on any Python project, and I was already using them.

The last chapter gives a few pointers on how to setup your application to have different behavior in production, development, and testing; reminds you to always test your application and shows a few tools to help you debug/optimize once you start having issues. In this chapter, I found something that looked super interesting: tracemalloc. Then I saw that it exists only in Python 3, and the project I’m working on is still using Python 2 🙁

All things considered, I’d recommend Effective Python: 59 Specific Ways to Write Better Python, but mostly for people that are starting in Python, or that are working on projects that do not use pip/virtual env/etc.

Do you have any advanced Python books you recommend? I’m looking into advanced topics, around the language and tools.

Thanks for reading !