Skip to content

Commit acba478

Browse files
committed
Add request utility methods
This commit introduces some commonly used request utility methods like get_locale, get_intent_name etc.
1 parent ad947bd commit acba478

File tree

5 files changed

+570
-10
lines changed

5 files changed

+570
-10
lines changed

ask-sdk-core/ask_sdk_core/utils/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@
1818
import sys
1919

2020
from ..__version__ import __version__
21-
from .predicate import is_canfulfill_intent_name, is_intent_name, is_request_type
21+
from .predicate import (
22+
is_canfulfill_intent_name, is_intent_name, is_request_type)
2223
from ask_sdk_runtime.utils import user_agent_info
24+
from .request_util import (
25+
get_slot, get_slot_value, get_account_linking_access_token,
26+
get_api_access_token, get_device_id, get_dialog_state, get_intent_name,
27+
get_locale, get_request_type, is_new_session, get_supported_interfaces)
2328

2429

2530
SDK_VERSION = __version__
Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights
4+
# Reserved.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License").
7+
# You may not use this file except in compliance with the License.
8+
# A copy of the License is located at
9+
#
10+
# http://aws.amazon.com/apache2.0/
11+
#
12+
# or in the "license" file accompanying this file. This file is
13+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
14+
# OF ANY KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations under the
16+
# License.
17+
#
18+
import typing
19+
20+
from ask_sdk_model.intent_request import IntentRequest
21+
from ask_sdk_model.supported_interfaces import SupportedInterfaces
22+
23+
if typing.TYPE_CHECKING:
24+
from ..handler_input import HandlerInput
25+
from typing import Optional, AnyStr
26+
from ask_sdk_model.slot import Slot
27+
from ask_sdk_model.dialog_state import DialogState
28+
29+
30+
def get_locale(handler_input):
31+
# type: (HandlerInput) -> AnyStr
32+
"""Return locale value from input request.
33+
34+
The method returns the ``locale`` value present in the request. More
35+
information about the locale can be found here :
36+
https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#request-locale
37+
38+
:param handler_input: The handler input instance that is generally
39+
passed in the sdk's request and exception components
40+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
41+
:return: Locale value from the request
42+
:rtype: str
43+
"""
44+
return handler_input.request_envelope.request.locale
45+
46+
47+
def get_request_type(handler_input):
48+
# type: (HandlerInput) -> AnyStr
49+
"""Return the type of the input request.
50+
51+
The method retrieves the request ``type`` of the input request. More
52+
information about the different request types are mentioned here :
53+
https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#request-body-parameters
54+
55+
:param handler_input: The handler input instance that is generally
56+
passed in the sdk's request and exception components
57+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
58+
:return: Type value of the input request
59+
:rtype: str
60+
"""
61+
return handler_input.request_envelope.request.object_type
62+
63+
64+
def get_intent_name(handler_input):
65+
# type: (HandlerInput) -> AnyStr
66+
"""Return the name of the intent request.
67+
68+
The method retrieves the intent ``name`` from the input request, only if
69+
the input request is an
70+
:py:class:`ask_sdk_model.intent_request.IntentRequest`. If the input
71+
is not an IntentRequest, a :py:class:`TypeError` is raised.
72+
73+
:param handler_input: The handler input instance that is generally
74+
passed in the sdk's request and exception components
75+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
76+
:return: Name of the intent request
77+
:rtype: str
78+
:raises: TypeError
79+
"""
80+
request = handler_input.request_envelope.request
81+
if isinstance(request, IntentRequest):
82+
return request.intent.name
83+
84+
raise TypeError("The provided request is not an IntentRequest")
85+
86+
87+
def get_account_linking_access_token(handler_input):
88+
# type: (HandlerInput) -> Optional[AnyStr]
89+
"""Return the access token in the request.
90+
91+
The method retrieves the user's ``accessToken`` from the input request.
92+
Once a user successfully enables a skill and links their Alexa
93+
account to the skill, the input request will have the user's
94+
access token. A `None` value is returned if there is no access token
95+
in the input request. More information on this can be found here :
96+
https://developer.amazon.com/docs/account-linking/add-account-linking-logic-custom-skill.html
97+
98+
:param handler_input: The handler input instance that is generally
99+
passed in the sdk's request and exception components
100+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
101+
:return: User account linked access token if available. None if not
102+
available
103+
:rtype: Optional[str]
104+
"""
105+
return handler_input.request_envelope.context.system.user.access_token
106+
107+
108+
def get_api_access_token(handler_input):
109+
# type: (HandlerInput) -> AnyStr
110+
"""Return the api access token in the request.
111+
112+
The method retrieves the ``apiAccessToken`` from the input request,
113+
which has the encapsulated information of permissions granted by the
114+
user. This token can be used to call Alexa-specific APIs. More information
115+
about this can be found here :
116+
https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#system-object
117+
118+
The SDK already includes this token in the API calls done through the
119+
`service_client_factory` in
120+
:py:class:`ask_sdk_core.handler_input.HandlerInput`.
121+
122+
:param handler_input: The handler input instance that is generally
123+
passed in the sdk's request and exception components
124+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
125+
:return: Api access token from the input request, which encapsulates any
126+
permissions consented by the user
127+
:rtype: str
128+
"""
129+
return handler_input.request_envelope.context.system.api_access_token
130+
131+
132+
def get_device_id(handler_input):
133+
# type: (HandlerInput) -> AnyStr
134+
"""Return the device id from the input request.
135+
136+
The method retrieves the `deviceId` property from the input request.
137+
This value uniquely identifies the device and is generally used as
138+
input for some Alexa-specific API calls. More information about this
139+
can be found here :
140+
https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#system-object
141+
142+
:param handler_input: The handler input instance that is generally
143+
passed in the sdk's request and exception components
144+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
145+
:return: Unique device id of the device used to send the alexa request
146+
:rtype: str
147+
"""
148+
return handler_input.request_envelope.context.system.device.device_id
149+
150+
151+
def get_dialog_state(handler_input):
152+
# type: (HandlerInput) -> Optional[DialogState]
153+
"""Return the dialog state enum from the intent request.
154+
155+
The method retrieves the `dialogState` from the intent request, if
156+
the skill's interaction model includes a dialog model. This can be
157+
used to determine the current status of user conversation and return
158+
the appropriate dialog directives if the conversation is not yet complete.
159+
More information on dialog management can be found here :
160+
https://developer.amazon.com/docs/custom-skills/define-the-dialog-to-collect-and-confirm-required-information.html
161+
162+
The method returns a ``None`` if there is no dialog model added or
163+
if the intent doesn't have dialog management. The method raises a
164+
:py:class:`TypeError` if the input is not an `IntentRequest`.
165+
166+
:param handler_input: The handler input instance that is generally
167+
passed in the sdk's request and exception components.
168+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
169+
:return: State of the dialog model from the intent request.
170+
:rtype: Optional[ask_sdk_model.dialog_state.DialogState]
171+
:raises: TypeError if the input is not an IntentRequest
172+
"""
173+
request = handler_input.request_envelope.request
174+
if isinstance(request, IntentRequest):
175+
return request.dialog_state
176+
177+
raise TypeError("The provided request is not an IntentRequest")
178+
179+
180+
def get_slot(handler_input, slot_name):
181+
# type: (HandlerInput, AnyStr) -> Optional[Slot]
182+
"""Return the slot information from intent request.
183+
184+
The method retrieves the slot information
185+
:py:class:`ask_sdk_model.slot.Slot` from the input intent request
186+
for the given ``slot_name``. More information on the slots can be
187+
found here :
188+
https://developer.amazon.com/docs/custom-skills/request-types-reference.html#slot-object
189+
190+
If there is no such slot, then a ``None``
191+
is returned. If the input request is not an
192+
:py:class:`ask_sdk_model.intent_request.IntentRequest`, a
193+
:py:class:`TypeError` is raised.
194+
195+
:param handler_input: The handler input instance that is generally
196+
passed in the sdk's request and exception components
197+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
198+
:param slot_name: Name of the slot that needs to be retrieved
199+
:type slot_name: str
200+
:return: Slot information for the provided slot name if it exists,
201+
or a `None` value
202+
:rtype: Optional[ask_sdk_model.slot.Slot]
203+
:raises: TypeError if the input is not an IntentRequest
204+
"""
205+
request = handler_input.request_envelope.request
206+
if isinstance(request, IntentRequest):
207+
if request.intent.slots is not None:
208+
return request.intent.slots.get(slot_name, None)
209+
else:
210+
return None
211+
212+
raise TypeError("The provided request is not an IntentRequest")
213+
214+
215+
def get_slot_value(handler_input, slot_name):
216+
# type: (HandlerInput, AnyStr) -> AnyStr
217+
"""Return the slot value from intent request.
218+
219+
The method retrieves the slot value from the input intent request
220+
for the given ``slot_name``. More information on the slots can be
221+
found here :
222+
https://developer.amazon.com/docs/custom-skills/request-types-reference.html#slot-object
223+
224+
If there is no such slot, then a :py:class:`ValueError` is raised.
225+
If the input request is not an
226+
:py:class:`ask_sdk_model.intent_request.IntentRequest`, a
227+
:py:class:`TypeError` is raised.
228+
229+
:param handler_input: The handler input instance that is generally
230+
passed in the sdk's request and exception components
231+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
232+
:param slot_name: Name of the slot for which the value has to be retrieved
233+
:type slot_name: str
234+
:return: Slot value for the provided slot if it exists
235+
:rtype: str
236+
:raises: TypeError if the input is not an IntentRequest. ValueError is
237+
slot doesn't exist
238+
"""
239+
slot = get_slot(handler_input=handler_input, slot_name=slot_name)
240+
241+
if slot is not None:
242+
return slot.value
243+
244+
raise ValueError(
245+
"Provided slot {} doesn't exist in the input request".format(
246+
slot_name))
247+
248+
249+
def get_supported_interfaces(handler_input):
250+
# type: (HandlerInput) -> SupportedInterfaces
251+
"""Retrieves the supported interfaces from input request.
252+
253+
The method returns an
254+
:py:class:`ask_sdk_model.supported_interfaces.SupportedInterfaces`
255+
object instance listing each interface that the device
256+
supports. For example, if ``supported_interfaces`` includes
257+
``audio_player``, then you know that the device supports streaming
258+
audio using the AudioPlayer interface. More information on
259+
`supportedInterfaces` can be found here :
260+
https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#system-object
261+
262+
:param handler_input: The handler input instance that is generally
263+
passed in the sdk's request and exception components
264+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
265+
:return: Instance of
266+
:py:class:`ask_sdk_model.supported_interfaces.SupportedInterfaces`
267+
mentioning which all interfaces the device supports
268+
:rtype: ask_sdk_model.supported_interfaces.SupportedInterfaces
269+
"""
270+
return (
271+
handler_input.request_envelope.context.system.device.
272+
supported_interfaces)
273+
274+
275+
def is_new_session(handler_input):
276+
# type: (HandlerInput) -> bool
277+
"""Return if the session is new for the input request.
278+
279+
The method retrieves the ``new`` value from the input request's
280+
session, which indicates if it's a new session or not. The
281+
:py:class:`ask_sdk_model.session.Session` is only included on all
282+
standard requests except ``AudioPlayer``, ``VideoApp`` and
283+
``PlaybackController`` requests. More information can be found here :
284+
https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#session-object
285+
286+
A :py:class:`TypeError` is raised if the input request doesn't have
287+
the ``session`` information.
288+
289+
:param handler_input: The handler input instance that is generally
290+
passed in the sdk's request and exception components
291+
:type handler_input: ask_sdk_core.handler_input.HandlerInput
292+
:return: Boolean if the session is new for the input request
293+
:rtype: bool
294+
:raises: TypeError if the input request doesn't have a session
295+
"""
296+
session = handler_input.request_envelope.session
297+
298+
if session is not None:
299+
return session.new
300+
301+
raise TypeError("The provided request doesn't have a session")

ask-sdk-core/ask_sdk_core/utils/viewport.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def get_orientation(width, height):
8787
8888
:type width: int
8989
:type height: int
90-
:return viewport orientation enum
90+
:return: viewport orientation enum
9191
:rtype: Orientation
9292
"""
9393
if width > height:
@@ -103,7 +103,7 @@ def get_size(size):
103103
"""Get viewport size from given size.
104104
105105
:type size: int
106-
:return viewport size enum
106+
:return: viewport size enum
107107
:rtype: Size
108108
"""
109109
if size in range(0, 600):
@@ -125,7 +125,7 @@ def get_dpi_group(dpi):
125125
"""Get viewport density group from given dpi.
126126
127127
:type dpi: int
128-
:return viewport density group enum
128+
:return: viewport density group enum
129129
:rtype: Density
130130
"""
131131
if dpi in range(0, 121):
@@ -157,8 +157,8 @@ def get_viewport_profile(request_envelope):
157157
158158
:param request_envelope: The alexa request envelope object
159159
:type request_envelope: ask_sdk_model.request_envelope.RequestEnvelope
160-
:return Calculated Viewport Profile enum
161-
:rtype ViewportProfile
160+
:return: Calculated Viewport Profile enum
161+
:rtype: ViewportProfile
162162
"""
163163
viewport_state = request_envelope.context.viewport
164164
if viewport_state:

0 commit comments

Comments
 (0)