Skill Attributes
This guide provides information on different scopes of attributes available to the skill developer, and how to use them in the skill.
Attributes
The SDK allows you to store and retrieve attributes at different scopes. For example, attributes can be used to store data that you retrieve on subsequent requests. You can also use attributes in your handler's can_handle
logic to add conditions during request routing.
An attribute consists of a key and a value. The key is enforced as a str
type and the value is an unbounded object
. For session and persistent attributes, you must ensure that value types are serializable so they can be properly stored for subsequent retrieval. This restriction does not apply to request-level attributes because they do not persist outside of the request processing lifecycle.
Attribute Scopes
Request Attributes
Request attributes only last within a single request processing lifecycle. Request attributes are initially empty when a request comes in, and are discarded once a response has been produced.
Request attributes are useful with request and response interceptors. For example, you can inject additional data and helper methods into request attributes through a request interceptor so they are retrievable by request handlers.
Session Attributes
Session attributes persist throughout the lifespan of the current skill session. Session attributes are available for use with any in-session request. Any attributes set during the request processing lifecycle are sent back to the Alexa service and provided in the next request in the same session.
Session attributes do not require the use of an external storage solution. They are not available for use when handling out-of-session requests. They are discarded once the skill session closes.
session
property of Alexa's ask_sdk_model.request_envelope.RequestEnvelope
and ask_sdk_model.response_envelope.ResponseEnvelope
objects, only serializable types can be stored under them. The ask_sdk_core.serialize.DefaultSerializer
is used to serialize / deserialize the values.Persistent Attributes
Persistent attributes persist beyond the lifecycle of the current session. How these attributes are stored, including key scope (user ID or device ID), TTL, and storage layer depends on the configuration of the skill.
PersistenceAdapter
. A call to the AttributesManager
to retrieve or save persistent attributes will raise an exception if the PersistenceAdapter
has not been configured.AttributesManager
The AttributesManager
exposes attributes that you can retrieve and update in your handlers. AttributesManager
is available to handlers via the Handler Input object. The AttributesManager
takes care of attributes retrieval and saving so that you can interact directly with attributes needed by your skill.
Interface
class AttributesManager(object):
def __init__(self, request_envelope, persistence_adapter=None):
# type: (RequestEnvelope, AbstractPersistenceAdapter) -> None
....
@property
def request_attributes(self):
# type: () -> Dict[str, Any]
# Request Attributes getter
....
@request_attributes.setter
def request_attributes(self, attributes):
# type: (Dict[str, Any]) -> None
# Request Attributes setter
....
@property
def session_attributes(self):
# type: () -> Dict[str, Any]
# Session Attributes getter
....
@session_attributes.setter
def session_attributes(self, attributes):
# type: (Dict[str, Any]) -> None
# Session Attributes setter
....
@property
def persistent_attributes(self):
# type: () -> Dict[str, Any]
# Persistence Attributes getter
# Uses the Persistence adapter to get the attributes
....
@persistent_attributes.setter
def persistent_attributes(self, attributes):
# type: (Dict[str, Any]) -> None
# Persistent Attributes setter
....
def save_persistent_attributes(self):
# type: () -> None
# Save the persistence attributes to the persistence layer
....
def delete_persistent_attributes(self):
# type: () -> None
# Delete the persistence attributes from the persistence layer
....
The following example shows how you can retrieve and save persistent attributes.
class PersistenceAttributesHandler(AbstractRequestHandler):
def can_handle(handler_input):
persistence_attr = handler_input.attributes_manager.persistent_attributes
return persistence_attr['foo'] == 'bar'
def handle(handler_input):
persistence_attr = handler_input.attributes_manager.persistent_attributes
persistence_attr['foo'] = 'baz'
handler_input.attributes_manager.save_persistent_attributes()
return handler_input.response_builder.response
AttributesManager
caches the persistent attributes locally. persistent_attributes
setter will only update the locally cached persistent attributes. You need to call save_persistent_attributes()
to save persistent attributes to the persistence layer.delete_attributes
on the default DynamoDbPersistenceAdapter
implementation will delete the persistence attributes from local cache as well as from the persistence layer (DynamoDB table).PersistenceAdapter
The AbstractPersistenceAdapter
is used by AttributesManager
when retrieving and saving attributes to persistence layer (i.e. database or local file system). You can register any customized PersistenceAdapter
that conforms to the AbstractPersistenceAdapter
interface with the SDK.
All implementations of AbstractPersistenceAdapter
needs to follow the following interface.
Interface
class AbstractPersistenceAdapter(object):
def get_attributes(self, request_envelope):
# type: (RequestEnvelope) -> Dict[str, Any]
pass
def save_attributes(self, request_envelope, attributes):
# type: (RequestEnvelope, Dict[str, Any]) -> None
pass
DynamoDBPersistenceAdapter
The ask-sdk-dynamodb-persistence-adapter
package provides an implementation of AbstractPersistenceAdapter
using AWS DynamoDB.
Interface
from ask_sdk_dynamodb.adapter import DynamoDbAdapter
adapter = DynamoDbAdapter(table_name, partition_key_name="id",
attribute_name="attributes", create_table=False,
partition_keygen=user_id_partition_keygen,
dynamodb_resource=boto3.resource("dynamodb")
Configuration Options
- table_name (string) - The name of the DynamoDB table used.
- partition_key_name (string) - Optional. The name of the partition key column. Default to
"id"
if not provided. - attributes_name (string) - Optional. The name of the attributes column. Default to
attributes
if not provided. - create_table (boolean) - Optional. Set to
True
to haveDynamoDbAdapter
automatically create the table if it does not exist. Default toFalse
if not provided. - partition_keygen (callable) - Optional. The function used to generate partition key using
RequestEnvelope
. Default to generate the partition key using theuser_id
. - dynamodb_resource (AWS.DynamoDB ServiceResource) - Optional. The
DynamoDBClient
used to query AWS DynamoDB table. You can inject yourDynamoDBClient
with custom configuration here. Default to useboto3.resource("dynamodb")
.
For more information, see DynamoDB Persistence Adapter.
S3PersistenceAdapter
The ask-sdk-s3-persistence-adapter package provides an implementation of AbstractPersistenceAdapter
using Amazon S3.
Interface
from ask_sdk_s3.adapter import S3Adapter
from ask_sdk_core.skill_builder import CustomSkillBuilder
s3_client = boto3.client('s3')
s3_adapter = S3Adapter(bucket_name="bucket_name",
path_prefix="path/prefix", s3_client=s3_client, object_keygen=user_id_keygen)
sb = CustomSkillBuilder(persistence_adapter=s3_adapter)
Configuration Options
- bucket_name (string) - The name of the S3 bucket used.
- path_prefix (string) - Optional. An S3 path prefix for the object. Defaults to no prefix if not provided.
- s3_client (S3.Client) - Optional. The S3 client is a representation of Amazon S3. It provides a simple interface to store, retrieve, and delete from the specified S3 bucket. You can inject your S3 client with custom configuration. The client defaults to use boto3.client('s3').
- object_keygen (string) - Optional. The function that uses
RequestEnvelope
to generate the object key. The default behavior is to generate the object key using theuser_id
.
For more information, see S3 Persistence Adapter.
Last updated: Nov 28, 2023