Skip to content

Enums

DEFAULT_OVERLAP_MODE: ExecutionMode = ExecutionMode.SINGLE module-attribute

Default overlap mode for registration/summary models when none is resolved yet.

DEFAULT_BACKPRESSURE_POLICY: BackpressurePolicy = BackpressurePolicy.BLOCK module-attribute

Default backpressure policy for registration/summary models when none is specified.

TERMINAL_STATUSES: frozenset[ResourceStatus] = frozenset({ResourceStatus.STOPPED, ResourceStatus.EXHAUSTED_DEAD}) module-attribute

Resource has reached an end state — shutdown can skip the STOPPING transition.

ACTIVE_STATUSES: frozenset[ResourceStatus] = frozenset({ResourceStatus.NOT_STARTED, ResourceStatus.STARTING, ResourceStatus.RUNNING}) module-attribute

Resource is in normal lifecycle progression (not failed, stopped, or exhausted).

ForgottenAwaitBehavior

Bases: StrEnum

Controls what happens when a protected method is called without await.

Source code in src/hassette/types/enums.py
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class ForgottenAwaitBehavior(StrEnum):
    """Controls what happens when a protected method is called without ``await``."""

    IGNORE = auto()
    """Suppress the warning entirely — the forgotten await is silently ignored."""

    WARN = auto()
    """Emit a ``HassetteForgottenAwaitWarning`` (default). Integrates with ``-W error``."""

    ERROR = auto()
    """Emit ``HassetteForgottenAwaitWarning`` in a form that ``filterwarnings("error")`` escalates
    to a raised exception. Under normal filters, behaves identically to ``WARN``."""

IGNORE = auto() class-attribute instance-attribute

Suppress the warning entirely — the forgotten await is silently ignored.

WARN = auto() class-attribute instance-attribute

Emit a HassetteForgottenAwaitWarning (default). Integrates with -W error.

ERROR = auto() class-attribute instance-attribute

Emit HassetteForgottenAwaitWarning in a form that filterwarnings("error") escalates to a raised exception. Under normal filters, behaves identically to WARN.

BlockingIOBehavior

Bases: StrEnum

Controls what happens when blocking I/O is detected on the shared event loop.

Source code in src/hassette/types/enums.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class BlockingIOBehavior(StrEnum):
    """Controls what happens when blocking I/O is detected on the shared event loop."""

    IGNORE = auto()
    """Suppress detection entirely — no warning AND no ``blocking_events`` row is written.
    This is the deliberate exception to the persist-before-warn rule: ``IGNORE`` means
    "I know this app blocks; treat it as if detection never fired," so there is no audit
    trail for ignored events."""

    WARN = auto()
    """Emit a ``HassetteBlockingIOWarning`` (default). Integrates with ``-W error``."""

    ERROR = auto()
    """Emit ``HassetteBlockingIOWarning`` in a form that ``filterwarnings("error")`` escalates
    to a raised exception. Under normal filters, behaves identically to ``WARN`` — the framework
    does not raise on its own; escalation requires the caller to install the error filter
    (``-W error``, a pytest ``filterwarnings`` marker, or ``warnings.filterwarnings`` at startup).

    The effect of escalation differs by detection tier:

    - **Tier 2 (call-site interception)** detects *before* the blocking primitive runs, so an
      escalated warning raises at the call site and prevents the blocking call from executing.
    - **Tier 1 (loop watchdog)** is warn-after: the stall has already completed when the warning
      fires on the off-loop daemon thread. The daemon suppresses the escalation to stay alive, so
      ``ERROR`` cannot retroactively interrupt a Tier 1 stall — it only records and warns."""

IGNORE = auto() class-attribute instance-attribute

Suppress detection entirely — no warning AND no blocking_events row is written. This is the deliberate exception to the persist-before-warn rule: IGNORE means "I know this app blocks; treat it as if detection never fired," so there is no audit trail for ignored events.

WARN = auto() class-attribute instance-attribute

Emit a HassetteBlockingIOWarning (default). Integrates with -W error.

ERROR = auto() class-attribute instance-attribute

Emit HassetteBlockingIOWarning in a form that filterwarnings("error") escalates to a raised exception. Under normal filters, behaves identically to WARN — the framework does not raise on its own; escalation requires the caller to install the error filter (-W error, a pytest filterwarnings marker, or warnings.filterwarnings at startup).

The effect of escalation differs by detection tier:

  • Tier 2 (call-site interception) detects before the blocking primitive runs, so an escalated warning raises at the call site and prevents the blocking call from executing.
  • Tier 1 (loop watchdog) is warn-after: the stall has already completed when the warning fires on the off-loop daemon thread. The daemon suppresses the escalation to stay alive, so ERROR cannot retroactively interrupt a Tier 1 stall — it only records and warns.

RestartType

Bases: StrEnum

Enumeration for service restart strategies.

Source code in src/hassette/types/enums.py
45
46
47
48
49
50
51
52
53
54
55
class RestartType(StrEnum):
    """Enumeration for service restart strategies."""

    PERMANENT = auto()
    """The service is permanent and should always be restarted on failure."""

    TRANSIENT = auto()
    """The service is transient — restarts on failure but supports cooldown cycling."""

    TEMPORARY = auto()
    """The service is temporary — once its restart budget is exhausted, it stops permanently."""

PERMANENT = auto() class-attribute instance-attribute

The service is permanent and should always be restarted on failure.

TRANSIENT = auto() class-attribute instance-attribute

The service is transient — restarts on failure but supports cooldown cycling.

TEMPORARY = auto() class-attribute instance-attribute

The service is temporary — once its restart budget is exhausted, it stops permanently.

ExecutionMode

Bases: StrEnum

Overlap behavior for a listener when a trigger fires while a prior invocation still runs.

Source code in src/hassette/types/enums.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
class ExecutionMode(StrEnum):
    """Overlap behavior for a listener when a trigger fires while a prior invocation still runs."""

    SINGLE = auto()
    """Drop the re-fire while a prior invocation is still running."""

    RESTART = auto()
    """Cancel the running invocation and start a new one."""

    QUEUED = auto()
    """Serialize triggers, running them one at a time in arrival order."""

    PARALLEL = auto()
    """Run invocations concurrently with no overlap guard (today's behavior)."""

SINGLE = auto() class-attribute instance-attribute

Drop the re-fire while a prior invocation is still running.

RESTART = auto() class-attribute instance-attribute

Cancel the running invocation and start a new one.

QUEUED = auto() class-attribute instance-attribute

Serialize triggers, running them one at a time in arrival order.

PARALLEL = auto() class-attribute instance-attribute

Run invocations concurrently with no overlap guard (today's behavior).

BackpressurePolicy

Bases: StrEnum

What a listener does when the global dispatch semaphore is saturated.

The semaphore is shared by all listeners across all apps — saturation means the whole bus is at capacity, not that this listener alone is busy. This is distinct from per-listener rate controls (debounce, throttle, mode), which operate inside the handler invoker after a dispatch slot is acquired.

Source code in src/hassette/types/enums.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
class BackpressurePolicy(StrEnum):
    """What a listener does when the *global* dispatch semaphore is saturated.

    The semaphore is shared by all listeners across all apps — saturation means
    the whole bus is at capacity, not that this listener alone is busy. This is
    distinct from per-listener rate controls (``debounce``, ``throttle``, ``mode``),
    which operate inside the handler invoker after a dispatch slot is acquired.
    """

    BLOCK = auto()
    """Wait for a dispatch slot — the default for all listeners.

    When the global semaphore is saturated, the dispatch loop blocks until a slot
    opens, then runs the handler. No events are lost; the cost is added latency.
    Omitting ``backpressure=`` on a subscription is identical to passing ``BLOCK``.
    """

    DROP_NEWEST = auto()
    """Skip this event when the global semaphore is saturated; never waits.

    The dispatch loop checks the semaphore without acquiring it. If saturated, no
    task is spawned, one drop is recorded on the listener, and the loop moves on.
    Under normal load (semaphore not locked), dispatches identically to ``BLOCK``.

    A ``DROP_NEWEST`` listener may not run at all during a sustained saturation
    period — every event it receives while the bus is full is dropped. Use ``BLOCK``
    for handlers that must run at least once, even under load.
    """

BLOCK = auto() class-attribute instance-attribute

Wait for a dispatch slot — the default for all listeners.

When the global semaphore is saturated, the dispatch loop blocks until a slot opens, then runs the handler. No events are lost; the cost is added latency. Omitting backpressure= on a subscription is identical to passing BLOCK.

DROP_NEWEST = auto() class-attribute instance-attribute

Skip this event when the global semaphore is saturated; never waits.

The dispatch loop checks the semaphore without acquiring it. If saturated, no task is spawned, one drop is recorded on the listener, and the loop moves on. Under normal load (semaphore not locked), dispatches identically to BLOCK.

A DROP_NEWEST listener may not run at all during a sustained saturation period — every event it receives while the bus is full is dropped. Use BLOCK for handlers that must run at least once, even under load.

Outcome

Bases: StrEnum

The result of handing a trigger to an ExecutionModeGuard.

Source code in src/hassette/types/enums.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
class Outcome(StrEnum):
    """The result of handing a trigger to an ``ExecutionModeGuard``."""

    RAN = auto()
    """The invocation was started immediately."""

    QUEUED_ACCEPTED = auto()
    """A ``queued`` trigger was accepted into the pending queue; it will run later."""

    SUPPRESSED = auto()
    """A ``single`` re-fire was dropped because a prior invocation is still running."""

    DROPPED = auto()
    """A ``queued`` trigger was dropped because the pending queue is at its cap."""

RAN = auto() class-attribute instance-attribute

The invocation was started immediately.

QUEUED_ACCEPTED = auto() class-attribute instance-attribute

A queued trigger was accepted into the pending queue; it will run later.

SUPPRESSED = auto() class-attribute instance-attribute

A single re-fire was dropped because a prior invocation is still running.

DROPPED = auto() class-attribute instance-attribute

A queued trigger was dropped because the pending queue is at its cap.

Topic

Bases: StrEnum

Event topic identifiers for the internal pub/sub bus.

Source code in src/hassette/types/enums.py
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
class Topic(StrEnum):
    """Event topic identifiers for the internal pub/sub bus."""

    # hassette events

    HASSETTE_EVENT_SERVICE_STATUS = "hassette.event.service_status"
    """Service status updates"""

    HASSETTE_EVENT_WEBSOCKET_CONNECTED = "hassette.event.websocket_connected"
    """WebSocket connection established"""

    HASSETTE_EVENT_WEBSOCKET_DISCONNECTED = "hassette.event.websocket_disconnected"
    """WebSocket connection lost"""

    HASSETTE_EVENT_FILE_WATCHER = "hassette.event.file_watcher"
    """File watcher events"""

    HASSETTE_EVENT_APP_LOAD_COMPLETED = "hassette.event.app_load_completed"
    """Application load completion events"""

    HASSETTE_EVENT_APP_STATE_CHANGED = "hassette.event.app_state_changed"
    """App instance state change events"""

    HASSETTE_EVENT_EXECUTION_COMPLETED = "hassette.event.execution_completed"
    """Handler or job execution persisted to the telemetry database"""

    # Home Assistant events

    HASS_EVENT_STATE_CHANGED = "hass.event.state_changed"
    """State change events"""

    HASS_EVENT_CALL_SERVICE = "hass.event.call_service"
    """Service call events"""

    HASS_EVENT_COMPONENT_LOADED = "hass.event.component_loaded"
    """Component loaded events"""

    HASS_EVENT_SERVICE_REGISTERED = "hass.event.service_registered"
    """Service registered events"""

    HASS_EVENT_SERVICE_REMOVED = "hass.event.service_removed"
    """Service removed events"""

    HASS_EVENT_LOGBOOK_ENTRY = "hass.event.logbook_entry"
    """Logbook entry events"""

    HASS_EVENT_USER_ADDED = "hass.event.user_added"
    """User added events"""

    HASS_EVENT_USER_REMOVED = "hass.event.user_removed"
    """User removed events"""

    HASS_EVENT_AUTOMATION_TRIGGERED = "hass.event.automation_triggered"
    """Automation triggered events"""

    HASS_EVENT_SCRIPT_STARTED = "hass.event.script_started"
    """Script started events"""

HASSETTE_EVENT_SERVICE_STATUS = 'hassette.event.service_status' class-attribute instance-attribute

Service status updates

HASSETTE_EVENT_WEBSOCKET_CONNECTED = 'hassette.event.websocket_connected' class-attribute instance-attribute

WebSocket connection established

HASSETTE_EVENT_WEBSOCKET_DISCONNECTED = 'hassette.event.websocket_disconnected' class-attribute instance-attribute

WebSocket connection lost

HASSETTE_EVENT_FILE_WATCHER = 'hassette.event.file_watcher' class-attribute instance-attribute

File watcher events

HASSETTE_EVENT_APP_LOAD_COMPLETED = 'hassette.event.app_load_completed' class-attribute instance-attribute

Application load completion events

HASSETTE_EVENT_APP_STATE_CHANGED = 'hassette.event.app_state_changed' class-attribute instance-attribute

App instance state change events

HASSETTE_EVENT_EXECUTION_COMPLETED = 'hassette.event.execution_completed' class-attribute instance-attribute

Handler or job execution persisted to the telemetry database

HASS_EVENT_STATE_CHANGED = 'hass.event.state_changed' class-attribute instance-attribute

State change events

HASS_EVENT_CALL_SERVICE = 'hass.event.call_service' class-attribute instance-attribute

Service call events

HASS_EVENT_COMPONENT_LOADED = 'hass.event.component_loaded' class-attribute instance-attribute

Component loaded events

HASS_EVENT_SERVICE_REGISTERED = 'hass.event.service_registered' class-attribute instance-attribute

Service registered events

HASS_EVENT_SERVICE_REMOVED = 'hass.event.service_removed' class-attribute instance-attribute

Service removed events

HASS_EVENT_LOGBOOK_ENTRY = 'hass.event.logbook_entry' class-attribute instance-attribute

Logbook entry events

HASS_EVENT_USER_ADDED = 'hass.event.user_added' class-attribute instance-attribute

User added events

HASS_EVENT_USER_REMOVED = 'hass.event.user_removed' class-attribute instance-attribute

User removed events

HASS_EVENT_AUTOMATION_TRIGGERED = 'hass.event.automation_triggered' class-attribute instance-attribute

Automation triggered events

HASS_EVENT_SCRIPT_STARTED = 'hass.event.script_started' class-attribute instance-attribute

Script started events

BlockReason

Bases: StrEnum

Reasons an app may be intentionally blocked from starting.

Source code in src/hassette/types/enums.py
187
188
189
190
191
class BlockReason(StrEnum):
    """Reasons an app may be intentionally blocked from starting."""

    ONLY_APP = auto()
    """Another app has the @only_app decorator, so this app is excluded."""

ONLY_APP = auto() class-attribute instance-attribute

Another app has the @only_app decorator, so this app is excluded.

ResourceStatus

Bases: StrEnum

Enumeration for resource status.

Source code in src/hassette/types/enums.py
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
class ResourceStatus(StrEnum):
    """Enumeration for resource status."""

    NOT_STARTED = auto()
    """The resource has not been started yet."""

    STARTING = auto()
    """The resource is in the process of starting."""

    RUNNING = auto()
    """The resource is currently running."""

    STOPPING = auto()
    """The resource is in the process of stopping."""

    STOPPED = auto()
    """The resource has been stopped without errors."""

    FAILED = auto()
    """The resource has failed with a recoverable error."""

    CRASHED = auto()
    """The resource has crashed unexpectedly and cannot recover."""

    EXHAUSTED_DEAD = auto()
    """The service's restart budget is exhausted with no further restarts (permanent end state)."""

    EXHAUSTED_COOLING = auto()
    """The service's restart budget is exhausted and a long cooldown is in progress."""

NOT_STARTED = auto() class-attribute instance-attribute

The resource has not been started yet.

STARTING = auto() class-attribute instance-attribute

The resource is in the process of starting.

RUNNING = auto() class-attribute instance-attribute

The resource is currently running.

STOPPING = auto() class-attribute instance-attribute

The resource is in the process of stopping.

STOPPED = auto() class-attribute instance-attribute

The resource has been stopped without errors.

FAILED = auto() class-attribute instance-attribute

The resource has failed with a recoverable error.

CRASHED = auto() class-attribute instance-attribute

The resource has crashed unexpectedly and cannot recover.

EXHAUSTED_DEAD = auto() class-attribute instance-attribute

The service's restart budget is exhausted with no further restarts (permanent end state).

EXHAUSTED_COOLING = auto() class-attribute instance-attribute

The service's restart budget is exhausted and a long cooldown is in progress.

ConnectionState

Bases: StrEnum

Enumeration for WebSocket connection states.

Source code in src/hassette/types/enums.py
234
235
236
237
238
239
240
241
242
243
244
class ConnectionState(StrEnum):
    """Enumeration for WebSocket connection states."""

    DISCONNECTED = auto()
    """The WebSocket connection is not established."""

    CONNECTING = auto()
    """The WebSocket connection is being established."""

    CONNECTED = auto()
    """The WebSocket connection is established and active."""

DISCONNECTED = auto() class-attribute instance-attribute

The WebSocket connection is not established.

CONNECTING = auto() class-attribute instance-attribute

The WebSocket connection is being established.

CONNECTED = auto() class-attribute instance-attribute

The WebSocket connection is established and active.

ResourceRole

Bases: StrEnum

Enumeration for resource roles.

Source code in src/hassette/types/enums.py
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
class ResourceRole(StrEnum):
    """Enumeration for resource roles."""

    CORE = auto()
    """Only used by Hassette directly, as it does not inherit from Resource."""

    BASE = auto()
    """The base role for all resources."""

    SERVICE = auto()
    """A service resource."""

    RESOURCE = auto()
    """A generic resource."""

    APP = auto()
    """An application resource."""

    UNKNOWN = auto()
    """An unknown or unclassified resource."""

CORE = auto() class-attribute instance-attribute

Only used by Hassette directly, as it does not inherit from Resource.

BASE = auto() class-attribute instance-attribute

The base role for all resources.

SERVICE = auto() class-attribute instance-attribute

A service resource.

RESOURCE = auto() class-attribute instance-attribute

A generic resource.

APP = auto() class-attribute instance-attribute

An application resource.

UNKNOWN = auto() class-attribute instance-attribute

An unknown or unclassified resource.