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.

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.

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

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 have DynamoDbAdapter automatically create the table if it does not exist. Default to False if not provided.
  • partition_keygen (callable) - Optional. The function used to generate partition key using RequestEnvelope. Default to generate the partition key using the user_id.
  • dynamodb_resource (AWS.DynamoDB ServiceResource) - Optional. The DynamoDBClient used to query AWS DynamoDB table. You can inject your DynamoDBClient with custom configuration here. Default to use boto3.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 the user_id.

For more information, see S3 Persistence Adapter.


Was this page helpful?

Last updated: Nov 28, 2023