Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gadgets skill #245

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
5 changes: 4 additions & 1 deletion flask_ask/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@
confirm_intent,
buy,
upsell,
refund
refund,
gadget,
animation,
animation_step
)
50 changes: 39 additions & 11 deletions flask_ask/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def init_app(self, app, path='templates.yaml'):
raise TypeError("route is a required argument when app is not None")

self.app = app

app.ask = self

app.add_url_rule(self._route, view_func=self._flask_view_func, methods=['POST'])
Expand Down Expand Up @@ -300,21 +300,21 @@ def wrapper(*args, **kw):
def on_purchase_completed(self, mapping={'payload': 'payload','name':'name','status':'status','token':'token'}, convert={}, default={}):
"""Decorator routes an Connections.Response to the wrapped function.

Request is sent when Alexa completes the purchase flow.
See https://developer.amazon.com/docs/in-skill-purchase/add-isps-to-a-skill.html#handle-results
Request is sent when Alexa completes the purchase flow.
See https://developer.amazon.com/docs/in-skill-purchase/add-isps-to-a-skill.html#handle-results


The wrapped view function may accept parameters from the Request.
In addition to locale, requestId, timestamp, and type


@ask.on_purchase_completed( mapping={'payload': 'payload','name':'name','status':'status','token':'token'})
def completed(payload, name, status, token):
logger.info(payload)
logger.info(name)
logger.info(status)
logger.info(token)

"""
def decorator(f):
self._intent_view_funcs['Connections.Response'] = f
Expand Down Expand Up @@ -522,6 +522,19 @@ def wrapper(*args, **kwargs):
return f
return decorator

def on_input_handler_event(self, mapping={}, convert={}, default={}):
def decorator(f):
self._intent_view_funcs['GameEngine.InputHandlerEvent'] = f
self._intent_mappings['GameEngine.InputHandlerEvent'] = mapping
self._intent_converts['GameEngine.InputHandlerEvent'] = convert
self._intent_defaults['GameEngine.InputHandlerEvent'] = default

@wraps(f)
def wrapper(*args, **kwargs):
self._flask_view_func(*args, **kwargs)
return f
return decorator

@property
def request(self):
return getattr(_app_ctx_stack.top, '_ask_request', None)
Expand Down Expand Up @@ -643,9 +656,9 @@ def unicode_to_wsgi(u):
body = json.dumps(event)
environ['CONTENT_TYPE'] = 'application/json'
environ['CONTENT_LENGTH'] = len(body)

PY3 = sys.version_info[0] == 3

if PY3:
environ['wsgi.input'] = io.StringIO(body)
else:
Expand Down Expand Up @@ -812,7 +825,8 @@ def _flask_view_func(self, *args, **kwargs):
# user can also access state of content.AudioPlayer with current_stream
elif 'Connections.Response' in request_type:
result = self._map_purchase_request_to_func(self.request.type)()

elif 'GameEngine' in request_type:
result = self._map_gadget_request_to_func(self.request.type)()
if result is not None:
if isinstance(result, models._Response):
return result.render_response()
Expand All @@ -833,7 +847,7 @@ def _map_intent_to_view_func(self, intent):
argspec = inspect.getfullargspec(view_func)
else:
argspec = inspect.getargspec(view_func)

arg_names = argspec.args
arg_values = self._map_params_to_view_args(intent.name, arg_names)

Expand All @@ -852,11 +866,11 @@ def _map_player_request_to_func(self, player_request_type):

def _map_purchase_request_to_func(self, purchase_request_type):
"""Provides appropriate parameters to the on_purchase functions."""

if purchase_request_type in self._intent_view_funcs:
view_func = self._intent_view_funcs[purchase_request_type]
else:
raise NotImplementedError('Request type "{}" not found and no default view specified.'.format(purchase_request_type))
raise NotImplementedError('Request type "{}" not found and no default view specified.'.format(purchase_request_type))

argspec = inspect.getargspec(view_func)
arg_names = argspec.args
Expand All @@ -865,6 +879,20 @@ def _map_purchase_request_to_func(self, purchase_request_type):
print('_map_purchase_request_to_func', arg_names, arg_values, view_func, purchase_request_type)
return partial(view_func, *arg_values)

def _map_gadget_request_to_func(self, gadget_request_type):
"""Provides appropriate parameters to the on_input_handler_event function."""

if gadget_request_type in self._intent_view_funcs:
view_func = self._intent_view_funcs[gadget_request_type]
else:
raise NotImplementedError('Request type "{}" not found and no default view specified.'.format(gadget_request_type))

argspec = inspect.getargspec(view_func)
arg_names = argspec.args
arg_values = self._map_params_to_view_args(gadget_request_type, arg_names)

return partial(view_func, *arg_values)

def _get_slot_value(self, slot_object):
slot_name = slot_object.name
slot_value = getattr(slot_object, 'value', None)
Expand Down
Loading