After a while I am sharing my fresh experience of Alexa skill using Flask-ask I developed for testing purpose. I gone through some tutorials and repositories to make it working. And finally I succeed with my first Alexa Skill. I used Flask Ask (Framework to rapid develop Alexa Skill with Python) and AWS Lambda. To getting started with how to create and deploy Alexa skill, I consider you have a basic knowledge of AWS Lambda and AWS S3. We are going to use following tools and technologies for through this process:
- Alexa Skill Account
- Python 3.6
- AWS S3
- AWS Lambda
- PyCharm (IDE for Python, I used)
You have to Copy some files from your current project. I my Python project’s directory structure (in PyCharm) is as follows:
Begning with Coding:
Just create a main file that will include all of the logic of your Alexa skill. You can give it any name like lambda_function.py etc. But I am using it as main.py We need this file to tell Lambda function to initialize our app and handle our source code.
1 2 3 4 5 6 | from flask import Flask, render_template from flask_ask import Ask, statement, question, session import json import random from random import randint import requests |
After importing required packages we need to write our welcome message, that Alexa will speak as we open our application in Alexa enabled devices.
1 2 3 | # Initialize the application app = Flask(__name__) ask = Ask(app, "/") |
Welcome message function:
1 2 3 4 5 6 7 8 9 | @ask.launch def start_skill(): """ This method is called when app is launched and new session created :return: json """ welcome_message = "Welcome to my new alexa skill." retry_speech = "Welcome to my text alexa skill. This is a retry / repeating message." return question(welcome_message).reprompt(retry_speech) |
Now create an handle function that will be called in AWS Lambda to initialize the application.
1 2 3 | # This function will be used for Lambda handler and is configured as main.lambda_function def lambda_handler(event, _context): return ask.run_aws_lambda(event) |
And you will call this handler by main.lambda_handler in AWS Lambda handler input field (please ignore if you are not familiar with AWS Lambda. I will explain it later in this tutorial). Here “main ” is the name of the root file in which you have written logic. And lambda_handler is the name of the function that will initialize the alexa skill. You may use any name for this function. And then same will be replaced in AWS Lambda function input field.
Don’t forget to handle exceptions. Otherwise session of your application will automatically get expired. In case if there is no intetnt defined in your alexa skill, Alexa will call automatically this function :
1 2 3 4 5 6 7 8 9 | @ask.default_intent def default_message(): """ This is called when Alexa does not understand any input :return: """ speech = "Oh-aw! I couldn't understand you. Do you need any assistant?" retry_speech = "How may I help you with my New Alexa Skill." return question(speech).reprompt(retry_speech) |
In above code I directly wrote statements. You can use YAML templates for the messages. With the YAML templates the above code will look like:
1 2 3 4 5 6 7 8 9 | @ask.default_intent def default_message(): """ This is called when Alexa does not understand any input :return: """ speech = render_template('help_message') retry_speech = render_template('help_message_again') return question(speech).reprompt(retry_speech) |
For using templates make sure you have created a templates.yaml file in your project’s root directory and define above varriables (‘help_message’ and ‘help_message_again’) in that as:
1 2 | help_message: Oops, I didn't get you. You can ask something like, Blah Blah Blah. help_message_again: Oh sorry, I didn't get you. Can you say something like, Blah Blah Blah. |
Note: templates.yaml is by default imported in Flask Ask framework. You don’t need to import it manually.
Now time to enable debugging our application. So put following code at the bottom of the main.py file.
1 2 3 4 5 6 7 | @ask.session_ended def session_ended(): return "{}", 200 if __name__ == '__main__': app.run(debug=True) |
Here is the full source of above skill’s logic (main.py):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | from flask import Flask, render_template from flask_ask import Ask, statement, question, session import json import random from random import randint import requests app = Flask(__name__) ask = Ask(app, "/") # This function will be used for Lambda handler and is configured as main.lambda_function def lambda_handler(event, _context): return ask.run_aws_lambda(event) @ask.launch def start_skill(): """ This method is called when app is launched and new session created :return: json """ welcome_message = "Welcome to my new alexa skill." retry_speech = "Welcome to my text alexa skill. This is a retry / repeating message." return question(welcome_message).reprompt(retry_speech) @ask.default_intent def default_message(): """ This is called when Alexa does not understand any input :return: """ speech = render_template('help_message') retry_speech = render_template('help_message_again') return question(speech).reprompt(retry_speech) @ask.session_ended def session_ended(): return "{}", 200 if __name__ == '__main__': app.run(debug=True) |
Now you have to make a build for deploying it to AWS Lambda. Here we will create a ZIP file and upload it to S3 bucket.
Most Important:
The structure of the ZIP file will be as :
-main.py
-templates.yaml
-and all the site-packages from path YOUR_PROJECT_ROOT_PATH/lib/python3.6/site-packages/*
In my case it’s /alexaStaging/suggestNearMe/lib/python3.6/site-packages/*
The structure will display look like as :
The directories in above screen are all the packages that needs run the app and to be automatically imported by our Lambda function Now create a zip file of above structure and upload it to AWS S3 bucket and get an URL of this ZIP. You need to build this zip and upload to S3 and get it’s URL every time when you want to deploy latest updates with your code to AWS Lambda.
Time to create a AWS Lambda function
Follow the steps displayed in the application:
Here you need Alexa Skill ID (You will get this id inside from developer.amazon.com Skill listiing page.) Currently Alexa Skill kit is offered in N. Virginia region of AWS. Sample Alexa skill id: amzn1.ask.skill.039yuc96-e5ca-4ba6-8803-bbdb001ws19c
After saving skill id time to add your S3 url that you got previously from uploading the zip file to AWS S3 Bucket.
Just paste the URL and in Handler input field enter your main file (that have all logic) name and it’s initialization function. In my case it’s main.py and the initialization function is lambda_handler. So I am entering value here as main.lambda_handler
Just save it. That’s all. Your Alexa skill using Flask-ask is ready to test. Now test your Alexa skill using Flask-ask in testing simulator / Alexa Echo Dot /any other alexa enabled device.