GithubHelp home page GithubHelp logo

anjishnu / ask-alexa-pykit Goto Github PK

View Code? Open in Web Editor NEW
275.0 30.0 58.0 166 KB

A minimalist SDK for developing skills for the Amazon Echo's ASK - Alexa Skills Kit using Amazon Web Services's Python Lambda Functions. Currently supported profiles are for Linux servers and AWS Lambda. Check the appropriate release branch. The cherrypy release branches have added components for request validation.

License: MIT License

Python 100.00%
alexa-skills-kit python aws-lambda alexa-pykit

ask-alexa-pykit's Introduction

ask-alexa-pykit

Release Version : Master (Unstable! For a stable release, check out the 0.5 branch)

ask-alexa-pykit 0.5 is out!

A minimalist framework for developing apps (skills) for the Amazon Echo's SDK: The Alexa Skills Kit (ASK).

Projects that use this library

Other Github Projects

If this library helps you build some dialog systems or do some interesting research - please remember to cite it!

  @Misc{kumarask2015,
  author =   {Anjishnu Kumar},
  title =    {ASK Alexa PyKit},
  howpublished = {\url{github.com/anjishnu/ask-alexa-pykit}},
  year = {2015}
  }

Let me know if you know any other projects that use or build on top of ask-alexa-pykit.

What does this library do?

  • Remove boiler plate from Alexa Skills Kit Code - maps intents directly to their handler functions.
  • Provide utils to quickly and effectively generate and manipulate sample utterances and the intent schema.
  • Provides python objects to quickly build alexa responses.
  • Automatic session management using session variables - your code gets access to a really simple interface for session management, you just add key value pairs to, or delete things from, a python dictionary, and this library along with the ASK platform takes care of the rest.

To use this code for your own skill, simply generate training data, and an intent schema definition and edit lambda_function.py to add handler functions for the intents and requests that your skill supports - this should be enough to get started.

Note: Unless someone asks me to reconsider - I am now only going to do further releases of this library for AWS Lambda - the core library is concise enough that it can be included into any python server framework with just a few imports. The old releases (for cherrypy) will contain the infuriating request validation parts of the library which can be useful for people who don't want to use the Lambda or LambdaProxy approach to skill development.

What's new?

Latest changes:

  • There's a pypi repo now https://pypi.python.org/pypi/ask-alexa-pykit/ - so you should be able to do pip install ask-alexa-pykit to use 'ask' as a standard python library or pip install ask-alexa-pykit --target new_skill_folder to install it into a directory (which will be your AWS Lambda Function directory).

  • Added an actual intent_schema.py module - thin wrapper around the JSON object which allows for easy manipulation, creation and serialization/deserialization. This module also doubles as the generate intent schema script now, with hooks to interactively generate the object.

  • The scripts folder is gone now - and the scripts themselves have been moved into the main alexa.ask module, which means that they can stay in sync with the Intent Schema and other config parameters without much fuss.

  • The annotation API has changed (become simpler) and the intent map computation and routing now happens under the hood. As of version 0.4 the VoiceHandler object now maintains an internal mapping of handler functions and now takes on the responsibility of handing off incoming requests to the right function end point.

  • Now there's only one module that a user has to be aware of. We've fully factored out the alexa specific bits into the ask library and you don't need to see how the mappings are computed.

  • The Request class got a minor upgrade - the addition of a 'metadata' field, which allows the developer to easily extend code to inject session, user or device specific metadata (after, for instance, querying a database) into a request object before it gets passed to the annotated handler functions.

  • The interface to the ask library function is now uniformly exposed to developers. A voice handler is now a subclass of a ResponseBuilder so that as a user all your really need to do is from ask import alexa

  • Improved session handling - no need to pass back the session attributes - just edit them in the dict and they'll automatically get propogated.

  • Python 2/3 dual compatibility

Basic overview of Classes:

  • The Request object contains information about the Alexa request - such as intent, slots, userId etc.

  • A VoiceHandler is an object that internally stores a mapping from intents and requests to their corresponding handler functions. These mappings are specified by a simple annotation scheme (see lambda_function.py for an example)

  • An alexa (VoiceHandler) annotated class (specified with an annotation) takes a request as an input, performs some arbitrary logic on top of it, and returns a Response.

  • The ResponseBuilder is an encapsulated way to construct responses for a VoiceHandler. A Response can be constructed by called ResponseBuilder.create_response.

Step 1: Download Code

Method 1:

$ git clone https://github.com/anjishnu/ask-alexa-pykit.git

Make sure you're in a python lambda release branch. E.g

$ cd ask-alexa-pykit
$ git checkout python_lambda_0.5_release

Otherwise your build my be broken since the master branch is not always stable.
Method 2:
$ mkdir my_new_skill
$ pip install ask-alexa-pykit --target my_new_skill

ask-alexa-pykit is now installed in your my_new_skill directory. Just import the library and start hacking.

Step 2: Create a intent schema for your app

Skip this if you're trying the included basic example and use sample_intent_schema.json as your INTENT_SCHEMA.


$ python -m ask.intent_schema -i FILEPATH

This script takes you through the process of generating an intent schema for your app- which defines how Alexa's language understanding system interprets results. After the process is complete, it asks you whether you the intent schema stored at the appropriate location.

Step 3: Generate training data and upload to Amazon.

3(a): Create a file containing your training examples and upload to Amazon. I've created a script which loads in the intent schema and does some validation and prompting while you type utterances, but I haven't played around with it enough to know if it actually helps.
$ python -m ask.write_sample -i INTENT_SCHEMA -o TRAINING_DATA_OUTPUT_LOCATION
This script prompts you to enter valid training data in the format defined by the ASK (https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/defining-the-voice-interface). You toggle through the different intents by pressing enter with blank input. Play around with it and see if you find it intuitive.

3(b): Once you are done, this script generates a file called utterance.txt with all your training data in it, ready to be uploaded to your skill: https://developer.amazon.com/edw/home.html#/skills

Step 4: Add your business logic

Skip this if you're just trying to run the included basic example.

Go to lambda_function.py and add handler functions to the code for your specific request or intent. This is what a handler function for NextRecipeIntent looks like.

@alexa.intent("NextRecipeIntent")
def next_recipe_intent_handler(request):
  """
  You can insert arbitrary business logic code here
  """
  return alexa.create_response("Getting Next Recipe ...")

Step 5: Package your code for Lambda

Package the code folder for AWS Lambda. Detailed instructions are here: http://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html

For the basic example included in the package simply zip the folder:
$ cd ask-alexa-pykit
$ zip -r ask-lambda.zip *

Step 6: Create a Lambda Function

  • Go to console.aws.amazon.com
  • Click on Lambda
  • Select [Virgina] on the top right. (ASK source is only available in Virginia)
  • Click on Create Lambda Function
  • Skip the Select Blueprint Section
  • In the configure step: choose a name e.g. alexa-pykit-demo
  • Choose Runtime as Python 2.7
  • Code Entry Type - Upload a zip file.
  • Upload ask-lambda.zip
  • For Role : create a new basic execution role
  • Press Next, and then Create Function
  • In the event source configuration pick event source type - Alexa Skills Kit.

Step 7: Associate Lambda Function with Alexa Skill

Add the ARN code for the Lambda Function you've just created as the Lambda ARN (Amazon Resource Name) Endpoint in the Skill Information tab of your skill's information on https://developer.amazon.com/edw/home.html#/skills/list

Note an ARN code is at the top of you Lambda page and starts with something like: arn:aws:lambda:us...

Contributing

  • The master branch is meant to be stable. I usually work on unstable stuff on a personal branch.

  • Fork the master branch ( https://github.com/[my-github-username]/ask-alexa-pykit/fork )

  • Create your branch (git checkout -b my-branch)

  • Commit your changes (git commit -am 'added fixes for something')

  • Push to the branch (git push origin my-branch)

  • Create a new Pull Request

  • And you're done!

  • Bug fixes, bug reports and new documentation are all appreciated!

Credits: Anjishnu Kumar 2015

ask-alexa-pykit's People

Contributors

anjishnu avatar hassanshamim avatar joegermuska avatar ysak-y avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ask-alexa-pykit's Issues

Cannot store new session attributes.

The end of the alexa_io.route_request reads as follows:

response = handler_fn(request)
response['sessionAttributes'] = request.session
return response

The request variable is the incoming request from Alexa which will always have None attributes unless we explicitly store some. This means that the code above removes any attributes we assign before returning the response.

I think the correct behaviour would be to simply remove the line that reassigns the attributes? This would allow the user to specify any sessionAttributes in their responses. To allow for this we modified the create_response method as so:

@classmethod
def create_response(self, message=None, end_session=False, card_obj=None,
                    reprompt_message=None, is_ssml=None, session_attributes=None):
   # ... Removed some stuff
   if session_attributes:
      response['sessionAttributes'] = session_attributes
   return response

Of course - it is likely I'm misunderstanding the intended usage! I'm happy to file a PR if you do want the above changes.

Support dialog 'context'

Overview

For example, we want to implement another function when YesIntent is passed. Because Yes is used some situation like Do you want to call to this hotel? or Do you want to book this hotel?. What can we recognize it?

To use context attribute, we can recognize what means 'Yes'.

So I want to add context option like alexa.create_response(text).with_context(context). and something logic for routing intent properly.

What do you think?

Install with --target fails

pip install --target Scratch/dev/alexa/simplesms/ ask-alexa-pykit
Collecting ask-alexa-pykit
Exception:
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 209, in main
    status = self.run(options, args)
  File "/usr/lib/python2.7/dist-packages/pip/commands/install.py", line 328, in run
    wb.build(autobuilding=True)
  File "/usr/lib/python2.7/dist-packages/pip/wheel.py", line 748, in build
    self.requirement_set.prepare_files(self.finder)
  File "/usr/lib/python2.7/dist-packages/pip/req/req_set.py", line 360, in prepare_files
    ignore_dependencies=self.ignore_dependencies))
  File "/usr/lib/python2.7/dist-packages/pip/req/req_set.py", line 512, in _prepare_file
    finder, self.upgrade, require_hashes)
  File "/usr/lib/python2.7/dist-packages/pip/req/req_install.py", line 276, in populate_link
    self.link = self._wheel_cache.cached_wheel(self.link, self.name)
  File "/usr/lib/python2.7/dist-packages/pip/wheel.py", line 68, in cached_wheel
    self._cache_dir, link, self._format_control, package_name)
  File "/usr/lib/python2.7/dist-packages/pip/wheel.py", line 137, in cached_wheel
    wheel = Wheel(wheel_name)
  File "/usr/lib/python2.7/dist-packages/pip/wheel.py", line 637, in __init__
    self.pyversions = wheel_info.group('pyver').split('.')
AttributeError: 'NoneType' object has no attribute 'split'

Instead passing install-purelib via install-option works:

pip install --install-option="--install-purelib=Scratch/dev/alexa/simplesms" ask-alexa-pykit

Needs better documentation

The README.md is ok general documentation if you already have experience with the package. However, it would be great if there was a walk-through where you re-create alexa-skills-kit-color-expert example but using ask-alexa-pykit.

Since color-expert / what's my fav color is the "hello world" of Alexa and is well documented on aws, it would be an outstanding example to use to show how it would be accomplished using ask-alexa-pykit. It was my goal to recreate it using your toolkit for the reason I outlined above.

How to elicit slot

The create response method doesn't seem documented in terms of how to do things like elicitSlot/ElicityIntent etc. if the create response method should not be responsible for this, I can't find how else to create responses back to alexa.

I would have anticipated it to look something like

alexa.elicit_slot(slot='myMissingSlot', message='can you please provide the missing detail about "missingSlot"')
the reason I do this is because the slot value may be present in the session (and so I shouldn't make it manditory), but not until it has been submitted the first time. Not sure how to do this with this library.

Failure to import IntentSchema

Line 6 of ask/write_sample.py

Change from intent_schema import IntentSchema to from ask.intent_schema import IntentSchema.

Python 3.5, installed via pip

Unit test suite

Come up with a suite of unit tests to ensure no degradation in functionality.

git checkout

whenever you checkout you have no write_sample.py in ask

Some errors on Readme.md and script

Hi,
I’ve found some problems on your Readme.md, point 2:

_$ python -m ask.intent_schema -i FILEPATH _ <--- Wrong Script!

is instead:

$ python -m ask.generate_intent_schema -i intents

On step6 you should add to "select [Virgina] on the top right", the other amazon's state doesn't have alexa skill available.

On the generate_intent_schema, if you select "0 Exit program" option, it fails brutally :)

  1. Exit program
    0
    Schema created:
    Traceback (most recent call last):
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "main", fname, loader, pkg_name)
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
    File "/Users/dega1999/Programming/Alexa/ask-alexa-pykit/alexa/ask/generate_intent_schema.py", line 91, in
    print (json.dumps(output, indent=2))
    NameError: name 'output' is not defined

BTW, I have succesfully loaded a new alexa skill, very fast, thanks to your work!
Thanks you!

Request Object should validate applicationId

Hey,

According to the Amazon guidelines for developing an Alexa skill, there should be some validation of Alexa requests within Lambda function codes.

https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/handling-requests-sent-by-alexa

The Request object seems like a good place to do that, since it's already doing some wrapping of Request JSONs anyways. I'm not sure how to go about raising an HTTP 400 Error without using some more robust framework, but I think this should at least raise an Assertion Error if the applicationIds don't line up

https://github.com/peterpanning/AlexaTransit/commit/2d7fdbcca77cd45514990be4fe478e417064cce6

Thoughts?

VoiceHandler error when deploying to Lambda

When I attempt to deploy my very simple Alexa skill to Lambda and test it, I get the following error in the logs:

module initialization error: 'VoiceHandler' object has no attribute 'default'

What information can I provide to help troubleshoot?

Dialogue Support

It's relatively hard to structure dialogue in Alexa Skills Kit. This library can supply some primitives to make life easier.

README.md - Step 3 - No module named ask.generate_training_data

version: 0.54
installed via: pip

$ python -m ask.generate_training_data -i intent_schema.json  -o .
/home/jlh/projects/alexa/bin/python: No module named ask.generate_training_data

The module generate_training_data only appears in the .5 branch and does not exist in the current version on pypi or the master branch.

The included basic example

Step 3a for the basic example says "go to 3b", but I don't understand what 3b means in this context. I don't see an utterance text file.

Perhaps because of this, when I complete all the steps, I do not understand what should happen. There are no Intent Schema or Sample Utterances in the Interaction Model.

Better Custom Slot Support

ask-alexa-pykit doesn't do anything to support custom slots - can we do something to make working with custom slots easier?

Revive server version or Unify with Lambda

After focusing on Lambda for a while to get the core library down - I think we are at the point that we can start looking at having a simple push-button server implementation as well.

The main issue with the server implementation is the SSL hell I had to go through when I wrote my first alexa skill: visible in gory detail here: https://github.com/anjishnu/ask-alexa-pykit/blob/cherrypy_0.3_release/lib/validation_utils.py

This also introduced a PyCrypto dependency (and literally shelling out to OpenSSL) to the library which was a big mess. We should be able to replicate this without relying on too many external libraries, and hopefully python's ssl module is up to the task.

I didn't want to spend too much time on it because it ended up in a dead end where it was impossible to publish anything because of the trusted SSL cert authority requirement - with this that might also be possible for free https://console.aws.amazon.com/acm/home?region=us-east-1#/firstrun/

Hey lets work togeather

Hello,

I just recently found out about this kit, but i've been writing my own alexa integration for django - it seems like there are a few core features that we could share between this package and mine. Would you be willing to work togeather on creating a library that both your project and my project use to handle those overlaps?

I've been working to isolate them in my codebase, have a look at everything under
https://github.com/rocktavious/django-alexa/tree/develop/django_alexa/internal

It's amazing how we've basically come up with very similar tech to cover the boiler plate.

I think it would be cool if we could come up with a good shared base and make that a package that our two libraries could leverage, because i'd also like to extend support to other web frameworks like Flask IE Flask-Alexa etc

It would be great to have such a wide package array all using the same core lib:

  • core lib (maybe "py-alexa")
    • Lambda Alexa
    • Django Alexa
    • Flask Alexa

Let me know what you think.

Usage of Alexa WITHOUT AWS / Lambda?

Is it possible to make use of the Alexa API on a local machine? Ie. I want to host my own script that will make calls to the API, get responses, and do other things accordingly.

Does the ask-alexa-pykit support that in any manner?

Handling session attributes

I'm still pretty new to Alexa development, but I find the session management kind of weird. It seems as though you have to make a point to send back session attributes every time, which is counter to web programming models where you can trust the framework to manage that.

If you and other people using this code are interested, I'd like to talk about a good approach to handling it, and I'm happy to implement it and/or test it since session management seems likely to be part of what I need.

It would be easy enough to expose what comes in as request['session']['attributes'] as something like request.session and just use it as a dictionary. But then in the current model, you'd need to remember to pass it to create_response -- some design which protected against forgetting to make that explicit seems worth looking for.

Issues deploying the sample app Basic on AWS

module initialization error: 'VoiceHandler' object has no attribute 'default'

I'm getting the above error message when attempting to deploy the same sample AWS skill as a lambda.

Error with generate_intent_schema.py

~/ask-alexa-pykit/scripts$ python3 generate_intent_schema.py File "generate_intent_schema.py", line 25 6 : ["AMAZON.US_CITY", ^ SyntaxError: invalid syntax

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.