Skip to content

Commit 72e1adb

Browse files
Shreyas-vgrnikhilym
authored andcommitted
Adding Template Resolvers for response generations (#114)
1 parent cd5c2a1 commit 72e1adb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2381
-34
lines changed

ask-sdk-core/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,4 @@ target/
6565

6666
# IntelliJ configs
6767
*.iml
68+
.idea/

ask-sdk-core/CHANGELOG.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ This release contains the following :
131131
1.10.2
132132
^^^^^^^
133133

134-
This release contains the following changes :
134+
This release contains the following changes :
135135

136-
- `Bug fix <https://github.com/alexa/alexa-skills-kit-sdk-for-python/pull/99>`__ on delete persistence attributes, to delete attributes without checking if they are set.
136+
- `Bug fix <https://github.com/alexa/alexa-skills-kit-sdk-for-python/pull/99>`__ on delete persistence attributes, to delete attributes without checking if they are set.
137137
- Fix `type hints <https://github.com/alexa/alexa-skills-kit-sdk-for-python/pull/95>`__ on lambda_handler.

ask-sdk-core/README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
====================================================
1+
====================================================
22
ASK SDK Core - Base components of Python ASK SDK
33
====================================================
44

@@ -40,7 +40,7 @@ Usage and Getting Started
4040
-------------------------
4141

4242
Getting started guides, SDK Features, API references, samples etc. can
43-
be found in the `technical documentation <https://developer.amazon.com/docs/alexa-skills-kit-sdk-for-python/overview.html>`_
43+
be found at `Read The Docs <https://alexa-skills-kit-python-sdk.readthedocs.io/en/latest/>`_
4444

4545

4646
Got Feedback?

ask-sdk-core/ask_sdk_core/dispatch_components/py.typed

Whitespace-only changes.

ask-sdk-core/ask_sdk_core/dispatch_components/request_components.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def process(self, handler_input, response):
103103
:type handler_input: HandlerInput
104104
:param response: Execution result of the Handler on
105105
handler input.
106-
:type response: Union[None, :py:class:`ask_sdk_model.Response`]
106+
:type response: Union[None, :py:class:`ask_sdk_model.response.Response`]
107107
:rtype: None
108108
"""
109109
raise NotImplementedError

ask-sdk-core/ask_sdk_core/exceptions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,13 @@ class PersistenceException(AskSdkException):
3939
class ApiClientException(AskSdkException):
4040
"""Exception class for ApiClient Adapter processing."""
4141
pass
42+
43+
44+
class TemplateLoaderException(AskSdkException):
45+
"""Exception class for Template Loaders"""
46+
pass
47+
48+
49+
class TemplateRendererException(AskSdkException):
50+
"""Exception class for Template Renderer"""
51+
pass

ask-sdk-core/ask_sdk_core/handler_input.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
#
1818
import typing
1919
from .response_helper import ResponseFactory
20+
from .view_resolvers import TemplateFactory
2021

2122
if typing.TYPE_CHECKING:
22-
from typing import Any
23+
from typing import Any, Dict
2324
from ask_sdk_model import RequestEnvelope
25+
from ask_sdk_model.response import Response
2426
from ask_sdk_model.services import ServiceClientFactory
2527
from .attributes_manager import AttributesManager
2628

@@ -48,11 +50,13 @@ class HandlerInput(object):
4850
for calling Alexa services
4951
:type service_client_factory:
5052
ask_sdk_model.services.service_client_factory.ServiceClientFactory
53+
:param template_factory: Template Factory to chain loaders and renderer
54+
:type template_factory: :py:class:`ask_sdk_core.view_resolver.TemplateFactory`
5155
"""
5256
def __init__(
5357
self, request_envelope, attributes_manager=None,
54-
context=None, service_client_factory=None):
55-
# type: (RequestEnvelope, AttributesManager, Any, ServiceClientFactory) -> None
58+
context=None, service_client_factory=None, template_factory=None):
59+
# type: (RequestEnvelope, AttributesManager, Any, ServiceClientFactory, TemplateFactory) -> None
5660
"""Input to Request Handler, Exception Handler and Interceptors.
5761
5862
:param request_envelope: Request Envelope passed from Alexa
@@ -68,12 +72,15 @@ def __init__(
6872
for calling Alexa services
6973
:type service_client_factory:
7074
ask_sdk_model.services.service_client_factory.ServiceClientFactory
75+
:param template_factory: Template Factory to chain loaders and renderer
76+
:type template_factory: :py:class:`ask_sdk_core.view_resolver.TemplateFactory`
7177
"""
7278
self.request_envelope = request_envelope
7379
self.context = context
7480
self.service_client_factory = service_client_factory
7581
self.attributes_manager = attributes_manager
7682
self.response_builder = ResponseFactory()
83+
self.template_factory = template_factory
7784

7885
@property
7986
def service_client_factory(self):
@@ -98,3 +105,19 @@ def service_client_factory(self, service_client_factory):
98105
ServiceClientFactory
99106
"""
100107
self._service_client_factory = service_client_factory
108+
109+
def generate_template_response(self, template_name, data_map, **kwargs):
110+
# type: (str, Dict, Any) -> Response
111+
"""Generate response using skill response template and injecting data.
112+
113+
:param template_name: name of response template
114+
:type template_name: str
115+
:param data_map: map contains injecting data
116+
:type data_map: Dict[str, object]
117+
:param kwargs: Additional keyword arguments for loader and renderer.
118+
:return: Skill Response output
119+
:rtype: :py:class:`ask_sdk_model.response.Response`
120+
"""
121+
return self.template_factory.process_template(
122+
template_name=template_name, data_map=data_map, handler_input=self,
123+
**kwargs)

ask-sdk-core/ask_sdk_core/py.typed

Whitespace-only changes.

ask-sdk-core/ask_sdk_core/skill.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from .serialize import DefaultSerializer
2828
from .handler_input import HandlerInput
2929
from .attributes_manager import AttributesManager
30+
from .view_resolvers import TemplateFactory
3031
from .utils import RESPONSE_FORMAT_VERSION, user_agent_info
3132
from .__version__ import __version__
3233

@@ -137,6 +138,8 @@ def __init__(self, skill_configuration):
137138
self.serializer = DefaultSerializer()
138139
self.skill_id = skill_configuration.skill_id
139140
self.custom_user_agent = skill_configuration.custom_user_agent
141+
self.loaders = skill_configuration.loaders
142+
self.renderer = skill_configuration.renderer
140143

141144
self.request_dispatcher = GenericRequestDispatcher(
142145
options=skill_configuration
@@ -185,6 +188,10 @@ def invoke(self, request_envelope, context):
185188
else:
186189
factory = None
187190

191+
template_factory = TemplateFactory(
192+
template_loaders=self.loaders,
193+
template_renderer=self.renderer)
194+
188195
attributes_manager = AttributesManager(
189196
request_envelope=request_envelope,
190197
persistence_adapter=self.persistence_adapter)
@@ -193,7 +200,8 @@ def invoke(self, request_envelope, context):
193200
request_envelope=request_envelope,
194201
attributes_manager=attributes_manager,
195202
context=context,
196-
service_client_factory=factory)
203+
service_client_factory=factory,
204+
template_factory=template_factory)
197205

198206
response = self.request_dispatcher.dispatch(
199207
handler_input=handler_input)

ask-sdk-core/ask_sdk_core/skill_builder.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@
2525
from .skill import CustomSkill, SkillConfiguration
2626

2727
if typing.TYPE_CHECKING:
28-
from typing import Callable, TypeVar, Dict
28+
from typing import Callable, TypeVar, Dict, List
2929
from ask_sdk_model.services import ApiClient
3030
from .attributes_manager import AbstractPersistenceAdapter
31+
from ask_sdk_runtime.view_resolvers import (
32+
AbstractTemplateLoader, AbstractTemplateRenderer)
3133
T = TypeVar('T')
3234

3335

@@ -39,7 +41,7 @@ class SkillBuilder(AbstractSkillBuilder):
3941
def __init__(self):
4042
# type: () -> None
4143
super(SkillBuilder, self).__init__()
42-
self.custom_user_agent = None
44+
self.custom_user_agent = None # type: str
4345
self.skill_id = None
4446

4547
@property
@@ -110,6 +112,32 @@ def wrapper(event, context):
110112
return skill.serializer.serialize(response_envelope) # type:ignore
111113
return wrapper
112114

115+
def add_custom_user_agent(self, user_agent):
116+
# type: (str) -> None
117+
"""Adds the user agent to the skill instance.
118+
119+
This method adds the passed in user_agent to the skill, which is
120+
reflected in the skill's response envelope.
121+
122+
:param user_agent: Custom User Agent string provided by the developer.
123+
:type user_agent: str
124+
:rtype: None
125+
"""
126+
if self.custom_user_agent is None:
127+
self.custom_user_agent = user_agent
128+
else:
129+
self.custom_user_agent += " {}".format(user_agent)
130+
131+
def add_renderer(self, renderer):
132+
# type: (AbstractTemplateRenderer) -> None
133+
"""Register renderer to generate template responses.
134+
135+
:param renderer: Renderer to render the template
136+
:type renderer: :py:class:`ask_sdk_runtime.view_resolvers.AbstractTemplateRenderer`
137+
"""
138+
super(SkillBuilder, self).add_renderer(renderer)
139+
self.add_custom_user_agent("templateResolver")
140+
113141

114142
class CustomSkillBuilder(SkillBuilder):
115143
"""Skill Builder with api client and persistence adapter setter

0 commit comments

Comments
 (0)