In April, we announced new helpers in the Alexa Skills Kit SDK for Python that allow you to locally run, test, and debug your Alexa skill faster. They also make it easier for you to deploy your skill backend as a web service built with Django or Flask.
If you are (or are thinking of) using AWS Lambda, testing and debugging may not be straightforward outside of using CloudWatch Logs. By adding a few lines of code, you can run any of your Alexa skills in Python on a local server, and use your favorite code editor to do step-by-step debugging and track down possible issues. This tutorial shows you how to set up a local Flask Server with a local DynamoDB instance for persistent storage and connect a debugger.
1. Install the flask-ask-sdk package through the pip command.
pip install the flask-ask-sdk
2. Import the SkillBuilder class from the ASK SDK core package. This class provides utility methods to construct the skill instance and create lambda integration handler.
from ask_sdk_core.skill_builder import SkillBuilder
from flask import Flask from flask_ask_sdk.skill_adapter import SkillAdapter
4. Then, create a Flask web server from the Flask module using the prompt below:
app = Flask(__name__)
5. Next, create your skill builder object by defining an instance of the SkillBuilder class.
sb = SkillBuilder()
6. If you want to test whether or not your Flask server is responding, you can also add the following lines to the code after creating the skill builder object. Once you start your server in Visual Studio Code, you can navigate to http://127.0.0.1:5000/ in your browser, where you should see the message “Hello, Flask!”
@app.route("/") def home(): return "Hello, Flask!"
7. Note that you can keep your intent handlers (Python classes) defined as they are.
sb.add_request_handler(LaunchRequestHandler()) sb.add_request_handler(HelpIntentHandler()) sb.add_request_handler(CancelOrStopIntentHandler()) sb.add_request_handler(SessionEndedRequestHandler()) sb.add_exception_handler(CatchAllExceptionHandler()) handler = sb.lambda_handler()
8. After the last line in the previous prompt, insert the code shown below. This will allow you to create a skill adapter to register your skill and dispatch the incoming requests. Then you can run your application.
skill_adapter = SkillAdapter( skill=sb.create(), skill_id=1, app=app) skill_adapter.register(app=app, route="/") if __name__ == '__main__': app.run()
Now that your skill is running as a local Flask server, we need to make it available as an endpoint to the Alexa cloud service.
First, download and install ngrok. To run ngrok, type the following command:
ngrok http -host-header="localhost:5000" 5000
Port 5000 is the port where your Flask server is running on. You should get an output like this:
The underlined ngrok URL displayed in the prompt above is the public URL you will use for your web service. This public URL can change every time you run your ngrok server, so this an example URL. If you want to test whether or not your public URL (https://9cdaeb58.ngrok.io in this example) is working as expected, you can just type it in your browser and you should see the message “Hello, Flask!” again. You can also inspect HTTPS request and response details running over the ngrok tunnels by navigating to http://localhost:4040 in a web browser.
Now that you have a public URL to connect to your skill backend, you can update the endpoint information.
1. In the developer console, click on the “Build” tab, then select “Endpoint.”
2. Select “HTTPS” under “Service Endpoint Type,” and then enter your public URL in the “Default Region” field. This will allow you to test your skill by running your backend on your local machine.
3. In the dropdown menu, select the SSL certificate option “My development endpoint is a subdomain of a domain that has a certificate from a trusted certificate authority”.
4. Now that your endpoint is defined, you can save it.
When you need to retain data during the skill session, you use session attributes. Session attributes exist while the session is open. Once the session ends, any attributes associated with that session are lost. If your skill needs to remember data across multiple sessions, you need to save that data in persistent storage such as DynamoDB or S3.
DynamoDB is a key-value and document database. You can download, install, and run a self-contained version of DynamoDB on your computer. This version will allow you to write and test applications without accessing the DynamoDB web service.
Once you’ve downloaded DynamoDB, navigate to the directory where you extracted DynamoDBLocal.jar, and type the following command:
java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar –sharedDb
The local DynamoDB uses port 8000 by default.
Next, take the following steps:
1. Import the boto3 module from the AWS SDK for Python. Boto is the Amazon Web Services (AWS) SDK for Python. It enables Python developers to create, configure, and manage AWS services such as DynamoDB.
2. Import the StandardSkillBuilder class from the Alexa Skills Kit (ASK) SDK standard. This provides Persistence and Service Client features. It also provides optional parameters for configuring the DynamoDB table options. Note that you no longer need to use the SkillBuilder class from the ASK SDK core package.
from ask_sdk.standard import StandardSkillBuilder
3. Create a resource object representing the local DynamoDB by defining the resource to be used and the endpoint where the local DynamoDB server is running on.
srvcResource = boto3.resource('dynamodb', endpoint_url='http://localhost:8000')
4. Create your skill builder object by using the constructor for the StandardSkillBuilder class. The constructor accepts three parameters: the name of the table you want to create; the flag indicating that the table will be created, if it does not exist; and the DynamoDB client, which is the resource object to be used.
sb = StandardSkillBuilder(table_name="meuwebserv", auto_create_table=True, dynamodb_client=srvcResource)
Then you just use your attributes manager object to interact with your persistent attributes. The attributes manager object is defined inside the handler_input object, available in each request handler implemented in your skill. A request handler is the code responsible for taking action on one or more types of incoming requests.
You can retrieve and save your persistent attributes to DynamoDB with the following prompts:
attr = handler_input.attributes_manager.persistent_attributes #update your session attributes handler_input.attributes_manager.save_persistent_attributes()
You are now ready to start testing and debugging your skill. You can use the Alexa simulator for testing the utterances. Visual Studio Code (or your favorite editor) can be used to set breakpoints in your code and do the step-by-step debugging.
Testing and debugging your Alexa skill with Lambda may not be a simple task if you are not using CloudWatch logs. With the new ASK SDK helpers, you can add a few lines of code and run any of your Alexa skills in Python on a local server. You can also use your favorite code editor to do step-by-step debugging and track down possible issues.