smartapp.interface

Classes that are part of the SmartApp interface.

Module Contents

smartapp.interface.AUTHORIZATION_HEADER = 'authorization'
smartapp.interface.CORRELATION_ID_HEADER = 'x-st-correlation'
smartapp.interface.DATE_HEADER = 'date'
class smartapp.interface.LifecyclePhase(*args, **kwds)

Bases: enum.Enum

Lifecycle phases.

CONFIRMATION = 'CONFIRMATION'
CONFIGURATION = 'CONFIGURATION'
INSTALL = 'INSTALL'
UPDATE = 'UPDATE'
UNINSTALL = 'UNINSTALL'
OAUTH_CALLBACK = 'OAUTH_CALLBACK'
EVENT = 'EVENT'
class smartapp.interface.ConfigValueType(*args, **kwds)

Bases: enum.Enum

Types of config values.

DEVICE = 'DEVICE'
STRING = 'STRING'
class smartapp.interface.ConfigPhase(*args, **kwds)

Bases: enum.Enum

Sub-phases within the CONFIGURATION phase.

INITIALIZE = 'INITIALIZE'
PAGE = 'PAGE'
class smartapp.interface.ConfigSettingType(*args, **kwds)

Bases: enum.Enum

Types of config settings.

DEVICE = 'DEVICE'
TEXT = 'TEXT'
BOOLEAN = 'BOOLEAN'
ENUM = 'ENUM'
PAGE = 'PAGE'
IMAGE = 'IMAGE'
ICON = 'ICON'
TIME = 'TIME'
PARAGRAPH = 'PARAGRAPH'
EMAIL = 'EMAIL'
DECIMAL = 'DECIMAL'
NUMBER = 'NUMBER'
PHONE = 'PHONE'
OAUTH = 'OAUTH'
class smartapp.interface.EventType(*args, **kwds)

Bases: enum.Enum

Supported event types.

DEVICE_COMMANDS_EVENT = 'DEVICE_COMMANDS_EVENT'
DEVICE_EVENT = 'DEVICE_EVENT'
DEVICE_HEALTH_EVENT = 'DEVICE_HEALTH_EVENT'
DEVICE_LIFECYCLE_EVENT = 'DEVICE_LIFECYCLE_EVENT'
HUB_HEALTH_EVENT = 'HUB_HEALTH_EVENT'
INSTALLED_APP_LIFECYCLE_EVENT = 'INSTALLED_APP_LIFECYCLE_EVENT'
MODE_EVENT = 'MODE_EVENT'
SCENE_LIFECYCLE_EVENT = 'SCENE_LIFECYCLE_EVENT'
SECURITY_ARM_STATE_EVENT = 'SECURITY_ARM_STATE_EVENT'
TIMER_EVENT = 'TIMER_EVENT'
WEATHER_EVENT = 'WEATHER_EVENT'
class smartapp.interface.SubscriptionType(*args, **kwds)

Bases: enum.Enum

Supported subscription types.

DEVICE = 'DEVICE'
CAPABILITY = 'CAPABILITY'
MODE = 'MODE'
DEVICE_LIFECYCLE = 'DEVICE_LIFECYCLE'
DEVICE_HEALTH = 'DEVICE_HEALTH'
SECURITY_ARM_STATE = 'SECURITY_ARM_STATE'
HUB_HEALTH = 'HUB_HEALTH'
SCENE_LIFECYCLE = 'SCENE_LIFECYCLE'
class smartapp.interface.BooleanValue

Bases: enum.StrEnum

String boolean values.

TRUE = 'true'
FALSE = 'false'
class smartapp.interface.AbstractRequest

Bases: abc.ABC

Abstract parent class for all types of lifecycle requests.

lifecycle: LifecyclePhase
execution_id: str
locale: str
version: str
class smartapp.interface.AbstractSetting

Bases: abc.ABC

Abstract parent class for all types of config settings.

id: str
name: str
description: str
required: bool | None = False
class smartapp.interface.DeviceSetting

Bases: AbstractSetting

A DEVICE setting.

type: ConfigSettingType
multiple: bool
capabilities: list[str]
permissions: list[str]
class smartapp.interface.TextSetting

Bases: AbstractSetting

A TEXT setting.

type: ConfigSettingType
default_value: str
class smartapp.interface.BooleanSetting

Bases: AbstractSetting

A BOOLEAN setting.

type: ConfigSettingType
default_value: BooleanValue
class smartapp.interface.EnumOption

An option within an ENUM setting

id: str
name: str
class smartapp.interface.EnumOptionGroup

A group of options within an ENUM setting

name: str
options: list[EnumOption]
class smartapp.interface.EnumSetting

Bases: AbstractSetting

An ENUM setting.

type: ConfigSettingType
multiple: bool
options: list[EnumOption] | None = None
grouped_options: list[EnumOptionGroup] | None = None
class smartapp.interface.LinkSetting

Bases: AbstractSetting

A LINK setting.

type: ConfigSettingType
url: str
image: str
class smartapp.interface.PageSetting

Bases: AbstractSetting

A PAGE setting.

type: ConfigSettingType
page: str
image: str
class smartapp.interface.ImageSetting

Bases: AbstractSetting

An IMAGE setting.

type: ConfigSettingType
image: str
class smartapp.interface.IconSetting

Bases: AbstractSetting

An ICON setting.

type: ConfigSettingType
image: str
class smartapp.interface.TimeSetting

Bases: AbstractSetting

A TIME setting.

type: ConfigSettingType
class smartapp.interface.ParagraphSetting

Bases: AbstractSetting

A PARAGRAPH setting.

type: ConfigSettingType
default_value: str
class smartapp.interface.EmailSetting

Bases: AbstractSetting

An EMAIL setting.

type: ConfigSettingType
class smartapp.interface.DecimalSetting

Bases: AbstractSetting

A DECIMAL setting.

type: ConfigSettingType
class smartapp.interface.NumberSetting

Bases: AbstractSetting

A NUMBER setting.

type: ConfigSettingType
class smartapp.interface.PhoneSetting

Bases: AbstractSetting

A PHONE setting.

type: ConfigSettingType
class smartapp.interface.OauthSetting

Bases: AbstractSetting

An OAUTH setting.

type: ConfigSettingType
browser: bool
url_template: str
smartapp.interface.ConfigSetting
class smartapp.interface.DeviceValue
device_id: str
component_id: str
class smartapp.interface.DeviceConfigValue

DEVICE configuration value.

device_config: DeviceValue
value_type: ConfigValueType
class smartapp.interface.StringValue
value: str
class smartapp.interface.StringConfigValue

STRING configuration value.

string_config: StringValue
value_type: ConfigValueType
smartapp.interface.ConfigValue
class smartapp.interface.InstalledApp

Installed application.

installed_app_id: str
location_id: str
config: dict[str, list[ConfigValue]]
permissions: list[str]
as_devices(key: str) list[DeviceValue]

Return a list of devices for a named configuration value.

as_str(key: str) str

Return a named configuration value, interpreted as a string

as_bool(key: str) bool

Return a named configuration value, interpreted as a boolean

as_int(key: str) int

Return a named configuration value, interpreted as an integer

as_float(key: str) float

Return a named configuration value, interpreted as a float

class smartapp.interface.Event

Holds the triggered event, one of several different attributes depending on event type.

event_time: arrow.Arrow | None = None
event_type: EventType
device_event: dict[str, Any] | None = None
device_lifecycle_event: dict[str, Any] | None = None
device_health_event: dict[str, Any] | None = None
device_commands_event: dict[str, Any] | None = None
mode_event: dict[str, Any] | None = None
timer_event: dict[str, Any] | None = None
scene_lifecycle_event: dict[str, Any] | None = None
security_arm_state_event: dict[str, Any] | None = None
hub_health_event: dict[str, Any] | None = None
installed_app_lifecycle_event: dict[str, Any] | None = None
weather_event: dict[str, Any] | None = None
weather_data: dict[str, Any] | None = None
air_quality_data: dict[str, Any] | None = None
for_type(event_type: EventType) dict[str, Any] | None

Return the attribute associated with an event type.

class smartapp.interface.ConfirmationData

Confirmation data.

app_id: str
confirmation_url: str
class smartapp.interface.ConfigInit

Initialization data.

id: str
name: str
description: str
permissions: list[str]
first_page_id: str
class smartapp.interface.ConfigRequestData

Configuration data provided on the request.

installed_app_id: str
phase: ConfigPhase
page_id: str
previous_page_id: str
config: dict[str, list[ConfigValue]]
class smartapp.interface.ConfigInitData

Configuration data provided in an INITIALIZATION response.

initialize: ConfigInit
class smartapp.interface.ConfigSection

A section within a configuration page.

name: str
settings: list[ConfigSetting]
class smartapp.interface.ConfigPage

A page of configuration data for the CONFIGURATION phase.

page_id: str
name: str
previous_page_id: str | None
next_page_id: str | None
complete: bool
sections: list[ConfigSection]
class smartapp.interface.ConfigPageData

Configuration data provided in an PAGE response.

page: ConfigPage
class smartapp.interface.InstallData

Install data.

auth_token: str
refresh_token: str
installed_app: InstalledApp
token() str

Return the auth token associated with this request.

app_id() str

Return the installed application id associated with this request.

location_id() str

Return the installed location id associated with this request.

as_devices(key: str) list[DeviceValue]

Return a list of devices for a named configuration value.

as_str(key: str) str

Return a named configuration value, interpreted as a string

as_bool(key: str) bool

Return a named configuration value, interpreted as a boolean

as_int(key: str) int

Return a named configuration value, interpreted as an integer

as_float(key: str) float

Return a named configuration value, interpreted as a float

class smartapp.interface.UpdateData

Update data.

auth_token: str
refresh_token: str
installed_app: InstalledApp
previous_config: dict[str, list[ConfigValue]] | None = None
previous_permissions: list[str]
token() str

Return the auth token associated with this request.

app_id() str

Return the installed application id associated with this request.

location_id() str

Return the installed location id associated with this request.

as_devices(key: str) list[DeviceValue]

Return a list of devices for a named configuration value.

as_str(key: str) str

Return a named configuration value, interpreted as a string

as_bool(key: str) bool

Return a named configuration value, interpreted as a boolean

as_int(key: str) int

Return a named configuration value, interpreted as an integer

as_float(key: str) float

Return a named configuration value, interpreted as a float

class smartapp.interface.UninstallData

Install data.

installed_app: InstalledApp
app_id() str

Return the installed application id associated with this request.

location_id() str

Return the installed location id associated with this request.

class smartapp.interface.OauthCallbackData
installed_app_id: str
url_path: str
class smartapp.interface.EventData

Event data.

auth_token: str
installed_app: InstalledApp
events: list[Event]
token() str

Return the auth token associated with this request.

app_id() str

Return the installed application id associated with this request.

location_id() str

Return the installed location id associated with this request.

for_type(event_type: EventType) list[dict[str, Any]]

Get all events for a particular event type, possibly empty.

filter(event_type: EventType, predicate: collections.abc.Callable[[dict[str, Any]], bool] | None = None) list[dict[str, Any]]

Apply a filter to a set of events with a particular event type.

class smartapp.interface.ConfirmationRequest

Bases: AbstractRequest

Request for CONFIRMATION phase

app_id: str
confirmation_data: ConfirmationData
settings: dict[str, Any]
class smartapp.interface.ConfirmationResponse

Response for CONFIRMATION phase

target_url: str
class smartapp.interface.ConfigurationRequest

Bases: AbstractRequest

Request for CONFIGURATION phase

configuration_data: ConfigRequestData
settings: dict[str, Any]
class smartapp.interface.ConfigurationInitResponse

Response for CONFIGURATION/INITIALIZE phase

configuration_data: ConfigInitData
class smartapp.interface.ConfigurationPageResponse

Response for CONFIGURATION/PAGE phase

configuration_data: ConfigPageData
class smartapp.interface.InstallRequest

Bases: AbstractRequest

Request for INSTALL phase

install_data: InstallData
settings: dict[str, Any]
token() str

Return the auth token associated with this request.

app_id() str

Return the installed application id associated with this request.

location_id() str

Return the installed location id associated with this request.

as_devices(key: str) list[DeviceValue]

Return a list of devices for a named configuration value.

as_str(key: str) str

Return a named configuration value, interpreted as a string

as_bool(key: str) bool

Return a named configuration value, interpreted as a boolean

as_int(key: str) int

Return a named configuration value, interpreted as an integer

as_float(key: str) float

Return a named configuration value, interpreted as a float

class smartapp.interface.InstallResponse

Response for INSTALL phase

install_data: dict[str, Any]
class smartapp.interface.UpdateRequest

Bases: AbstractRequest

Request for UPDATE phase

update_data: UpdateData
settings: dict[str, Any]
token() str

Return the auth token associated with this request.

app_id() str

Return the installed application id associated with this request.

location_id() str

Return the installed location id associated with this request.

as_devices(key: str) list[DeviceValue]

Return a list of devices for a named configuration value.

as_str(key: str) str

Return a named configuration value, interpreted as a string

as_bool(key: str) bool

Return a named configuration value, interpreted as a boolean

as_int(key: str) int

Return a named configuration value, interpreted as an integer

as_float(key: str) float

Return a named configuration value, interpreted as a float

class smartapp.interface.UpdateResponse

Response for UPDATE phase

update_data: dict[str, Any]
class smartapp.interface.UninstallRequest

Bases: AbstractRequest

Request for UNINSTALL phase

uninstall_data: UninstallData
settings: dict[str, Any]
app_id() str

Return the installed application id associated with this request.

location_id() str

Return the installed location id associated with this request.

class smartapp.interface.UninstallResponse

Response for UNINSTALL phase

uninstall_data: dict[str, Any]
class smartapp.interface.OauthCallbackRequest

Bases: AbstractRequest

Request for OAUTH_CALLBACK phase

o_auth_callback_data: OauthCallbackData
class smartapp.interface.OauthCallbackResponse

Response for OAUTH_CALLBACK phase

o_auth_callback_data: dict[str, Any]
class smartapp.interface.EventRequest

Bases: AbstractRequest

Request for EVENT phase

event_data: EventData
settings: dict[str, Any]
token() str

Return the auth token associated with this request.

app_id() str

Return the installed application id associated with this request.

location_id() str

Return the installed location id associated with this request.

class smartapp.interface.EventResponse

Response for EVENT phase

event_data: dict[str, Any]
smartapp.interface.LifecycleRequest
smartapp.interface.LifecycleResponse
smartapp.interface.REQUEST_BY_PHASE
smartapp.interface.CONFIG_VALUE_BY_TYPE
smartapp.interface.CONFIG_SETTING_BY_TYPE
exception smartapp.interface.SmartAppError

Bases: Exception

An error tied to the SmartApp implementation.

message: str
correlation_id: str | None = None
exception smartapp.interface.InternalError

Bases: SmartAppError

An internal error was encountered processing a lifecycle event.

exception smartapp.interface.BadRequestError

Bases: SmartAppError

A lifecycle event was invalid.

exception smartapp.interface.SignatureError

Bases: SmartAppError

The request signature on a lifecycle event was invalid.

class smartapp.interface.SmartAppDispatcherConfig

Configuration for the SmartAppDispatcher.

Any production SmartApp should always check signatures. We support disabling that feature to make local testing easier during development.

BEWARE: setting log_json to True will potentially place secrets (such as authorization keys) in your logs. This is intended for use during development and debugging only.

check_signatures

Whether to check the digital signature on lifecycle requests

Type:

bool

clock_skew_sec

Amount of clock skew allowed when verifying digital signatures, or None to allow any skew

Type:

int

keyserver_url

The SmartThings keyserver URL, where we retrieve keys for signature checks

Type:

str

log_json

Whether to log JSON data at DEBUG level when processing requests

Type:

bool

check_signatures: bool = True
clock_skew_sec: int | None = 300
keyserver_url: str = 'https://key.smartthings.com'
log_json: bool = False
class smartapp.interface.SmartAppEventHandler

Bases: abc.ABC

Application event handler for SmartApp lifecycle events.

Inherit from this class to implement your own application-specific event handler. The application-specific event handler is always called first, before any default event handler logic in the dispatcher itself.

The correlation id is an optional value that you can associate with your log messages. It may aid in debugging if you need to contact SmartThings for support.

Some lifecycle events do not require you to implement any custom event handler logic:

  • CONFIRMATION: normally no callback needed, since the dispatcher logs the app id and confirmation URL

  • CONFIGURATION: normally no callback needed, since the dispatcher has the information it needs to respond

  • INSTALL/UPDATE: set up or replace subscriptions and schedules and persist required data, if any

  • UNINSTALL: remove persisted data, if any

  • OAUTH_CALLBACK: coordinate with your oauth provider as needed

  • EVENT: handle SmartThings events or scheduled triggers

The EventRequest object that you receive for the EVENT callback includes an authorization token and also the entire configuration bundle for the installed application. So, if your SmartApp is built around event handling and scheduled actions triggered by SmartThings, your handler can probably be stateless. There is probably is not any need to persist any of the data returned in the INSTALL or UPDATE lifecycle events into your own data store.

Note that SmartAppHandler is a synchronous and single-threaded interface. The assumption is that if you need high-volume asynchronous or multi-threaded processing, you will implement that at the tier above this where the actual POST requests are accepted from remote callers.

abstractmethod handle_confirmation(correlation_id: str | None, request: ConfirmationRequest) None

Handle a CONFIRMATION lifecycle request

abstractmethod handle_configuration(correlation_id: str | None, request: ConfigurationRequest) None

Handle a CONFIGURATION lifecycle request.

abstractmethod handle_install(correlation_id: str | None, request: InstallRequest) None

Handle an INSTALL lifecycle request.

abstractmethod handle_update(correlation_id: str | None, request: UpdateRequest) None

Handle an UPDATE lifecycle request.

abstractmethod handle_uninstall(correlation_id: str | None, request: UninstallRequest) None

Handle an UNINSTALL lifecycle request.

abstractmethod handle_oauth_callback(correlation_id: str | None, request: OauthCallbackRequest) None

Handle an OAUTH_CALLBACK lifecycle request.

abstractmethod handle_event(correlation_id: str | None, request: EventRequest) None

Handle an EVENT lifecycle request.

class smartapp.interface.SmartAppConfigPage

A page of configuration for the SmartApp.

page_name: str
sections: list[ConfigSection]
class smartapp.interface.SmartAppDefinition

The definition of the SmartApp.

All of this data would normally be static for any given version of your application. If you wish, you can maintain the definition in YAML or JSON in your source tree and parse it with smartapp.converter.CONVERTER.

Keep in mind that the JSON or YAML format on disk will be consistent with the SmartThings lifecycle API, so it will use camel case attribute names (like configPages) rather than the Python attribute names you see in source code (like config_pages).

id

Identifier for this SmartApp

Type:

str

name

Name of the SmartApp

Type:

str

description

Description of the SmartApp

Type:

str

permissions

Permissions that the SmartApp requires

Type:

List[str]

config_pages

Configuration pages that the SmartApp will offer users

Type:

List[SmartAppConfigPage]

id: str
name: str
description: str
target_url: str
permissions: list[str]
config_pages: list[SmartAppConfigPage] | None
class smartapp.interface.SmartAppConfigManager

Bases: abc.ABC

Configuration manager, used by the dispatcher to respond to CONFIGURATION events.

The dispatcher has a default configuration manager. However, you can implement your own if that default behavior does not meet your needs. For instance, a static config definition is adequate for lots of SmartApps, but it doesn’t work for some types of complex configuration, where the responses need to be generated dynamically. In that case, you can implement your own configuration manager with that specialized behavior.

This abstract class also includes several convenience methods to make it easier to build responses.

handle_initialize(_request: ConfigurationRequest, definition: SmartAppDefinition) ConfigurationInitResponse

Handle a CONFIGURATION INITIALIZE lifecycle request.

abstractmethod handle_page(request: ConfigurationRequest, definition: SmartAppDefinition, page_id: int) ConfigurationPageResponse

Handle a CONFIGURATION PAGE lifecycle request.

build_init_response(id: str, name: str, description: str, permissions: list[str], first_page_id: int) ConfigurationInitResponse

Build a ConfigurationInitResponse.

build_page_response(page_id: int, name: str, previous_page_id: int | None, next_page_id: int | None, complete: bool, sections: list[ConfigSection]) ConfigurationPageResponse

Build a ConfigurationPageResponse.

class smartapp.interface.SmartAppRequestContext

The context for a SmartApp lifecycle request.

headers

The request headers

Type:

Mapping[str, str]

body

The body of the request as string

Type:

str

headers: collections.abc.Mapping[str, str]
body: str = ''
normalized: collections.abc.Mapping[str, str]
correlation_id: str
signature: str
date: str
header(name: str) str | None

Return the named header case-insensitively, or None if not found.