rogulski.it

My name is Piotr, a passionate pythonista and this is my blog!

    How to create Alexa Skill using Python

    Posted at — Nov 7, 2018

    Alexa Python Header

    Lately, I’ve built a couple of applications for Alexa devices. I found out that a lot of people started to be interested in Alexa skill kit in terms of building or using the applications. If you will go to Alexa Skill Shop you can find a lot of apps starting on simple voice bot through smart home skills and ending with top music app players.

    Let’s build an application that can tell a joke from icndb.

    Alexa allows using HTTP webhooks or lambda functions as a communication between your system and end-user device. It is recommended to use lambda functions if the whole system is built on top of Amazon Services.

    In this tutorial, I would like to show you how simple it is to create webhooks and pin them up in Alexa Skill console.

    Requirements:

    Getting started

    Install alexa-skill package to simplify Alexa usage:

    pip install alexa-skill
    

    Each Alexa skill needs to specify build-in intents.

    from alexa_skill.intents import BuildInIntents
    
    buildin_intents = BuildInIntents(
        help_message='Say to Alexa: "tell me a joke"',
        not_handled_message="Sorry, I don't understand you. Could you repeat?",
        stop_message='stop',
        cancel_message='cancel',
    )
    

    Implement a key intent which will return random joke using BaseIntents class:

    import requests
    from alexa_skill.intents import BaseIntents
    
    class JokeIntents(BaseIntents):
        @property
        def mapper(self):
            return {'random_joke': self.random_joke}
    
        def random_joke(self):
            joke_response = requests.get('http://api.icndb.com/jokes/random')
            if joke_response.status_code != 200:
                return self.response('Sorry, I did not find any joke. Please try again'), False
    
            return self.response(joke_response['value']['joke']), True
    

    Mapped methods should return Alexa response and True if the response was successfully handled, otherwise False.

    This is very helpful when analytics tools need to be connected. For chatbots, I recommend to use Chatbase.

    All requests which are coming from a platform should be handled by one webhook. To do this I will use falcon web framework:

    # webhook.py
    import logging
    import alexa_skill
    import falcon
    
    class Fulfiller(object):
        def on_post(self, req, resp):
            get_response = alexa_skill.Processor(
                req.media,
                buildin_intents,
                'Welcome to joke teller. Would you like to hear a joke?',
                'Good bye',
                JokeIntents(), # Add implemented intent
            )
            json_response, handled = get_response()
            logging.info('Response was handled by system: {}'.format(handled))
            resp.media = json_response
            
    app = falcon.API(media_type=falcon.MEDIA_JSON)
    app.add_route('/v1/alexa/fulfiller', Fulfiller())
    

    Testing local webhook

    Alexa requires an endpoint secured with https. To develop and test webhook served from a local machine I recommend to use ngrok. It simply exposes local servers behind NATs and firewalls to the public internet over secure tunnels.

    1. Download https://ngrok.com/download

    2. Setup local server

    $ pip install gunicorn
    $ gunicorn webhook:app
    
    1. Start ngrok
    $ ./ngrok http 80
    
    ngrok by @inconshreveable 
    
    Session Status                online
    Session Expires               7 hours, 59 minutes
    Version                       2.2.8
    Region                        United States (us)
    Web Interface                 http://127.0.0.1:4040
    Forwarding                    http://0374b9cf.ngrok.io -> localhost:8000
    Forwarding                    https://0374b9cf.ngrok.io -> localhost:8000
    
    Connections                   ttl     opn     rt1     rt5     p50     p90
                                  0       0       0.00    0.00    0.00    0.00
    
    1. Copy and use forwarding url

    Alexa console setup

    1. Go to alexa console and create skill

    2. Go to Intents tab and add new intent

    alexa console 1

    1. Add sample utterances, something like Tell me a joke, Make me laugh etc…

    sample utterances

    1. Add ngrok webhook url

    alexa endpoint

    1. Go to test tab and enable tests for a skill

    2. From now on your webhook is ready to use

    3. You can test it on simulator or Alexa device

    Summary

    Alexa skill development is very simple. All you need to know is basic Python Programming language knowledge, one of the web frameworks like Django, Flask, Falcon or other… and that is all!

    You don’t need to know Amazon Web services to create a voice application but you can become AWS Alexa skill developer. You can easily develop and test your Alexa skill using ngrok which will expose your local Python server to the web without deploying it to the remote server.

    A good idea, user-friendly utterances and well defined Alexa responses are the keys to success.