Skip to content
Open
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