Home AssistantHome AssistantContributors
On this page

An integration can take part in backups in two ways, both in a backup.py platform file:

  • A backup agent stores backups somewhere: a network share, a cloud storage service, or anything else. Users pick the agents in the backup settings.
  • Pre and post hooks pause or prepare your integration before a backup, and resume after it.

Add a backup agent

A backup agent extends BackupAgent from homeassistant.components.backup, and implements five methods:

Python
from collections.abc import AsyncIterator, Callable, Coroutine
from typing import Any

from homeassistant.components.backup import (
    AgentBackup,
    BackupAgent,
    BackupAgentError,
    BackupNotFound,
    OnProgressCallback,
)


class ExampleBackupAgent(BackupAgent):
    """Store backups at Example."""

    domain = DOMAIN

    def __init__(self, entry: ExampleConfigEntry) -> None:
        """Initialize the agent."""
        super().__init__()
        self._client = entry.runtime_data
        self.name = entry.title
        self.unique_id = entry.entry_id

    async def async_upload_backup(
        self,
        *,
        open_stream: Callable[[], Coroutine[Any, Any, AsyncIterator[bytes]]],
        backup: AgentBackup,
        on_progress: OnProgressCallback,
        **kwargs: Any,
    ) -> None:
        """Upload a backup."""

    async def async_download_backup(
        self, backup_id: str, **kwargs: Any
    ) -> AsyncIterator[bytes]:
        """Download a backup."""

    async def async_delete_backup(self, backup_id: str, **kwargs: Any) -> None:
        """Delete a backup."""

    async def async_list_backups(self, **kwargs: Any) -> list[AgentBackup]:
        """List the backups."""

    async def async_get_backup(
        self, backup_id: str, **kwargs: Any
    ) -> AgentBackup:
        """Return one backup."""
  • domain, name, and unique_id identify the agent. Keep unique_id stable.
  • async_upload_backup gets a function that opens a stream of the backup, and the metadata of the backup in backup.
  • async_download_backup, async_delete_backup, and async_get_backup raise BackupNotFound when the backup does not exist.
  • On any other error, raise BackupAgentError, or an exception that extends it. Other exceptions are not expected to leave the agent.

Report upload progress

Call on_progress while you upload, for example after each chunk, with the total number of bytes uploaded so far. Home Assistant uses it to show the progress of the upload in the UI.

Python
on_progress(bytes_uploaded=bytes_sent)

Tell Home Assistant about your agents

Home Assistant gets your agents from two functions in backup.py:

Python
from homeassistant.core import HomeAssistant, callback


async def async_get_backup_agents(hass: HomeAssistant) -> list[BackupAgent]:
    """Return the backup agents."""
    return [
        ExampleBackupAgent(entry)
        for entry in hass.config_entries.async_loaded_entries(DOMAIN)
    ]


@callback
def async_register_backup_agents_listener(
    hass: HomeAssistant,
    *,
    listener: Callable[[], None],
    **kwargs: Any,
) -> Callable[[], None]:
    """Register a listener for when agents are added or removed."""
    hass.data.setdefault(DATA_BACKUP_AGENT_LISTENERS, []).append(listener)

    @callback
    def remove_listener() -> None:
        """Remove the listener."""
        hass.data[DATA_BACKUP_AGENT_LISTENERS].remove(listener)

    return remove_listener

Call the listeners whenever your agents change, so Home Assistant asks for them again. For agents that follow config entries, call them when an entry is loaded or unloaded, in async_setup_entry:

Python
def _notify_backup_listeners() -> None:
    for listener in hass.data.get(DATA_BACKUP_AGENT_LISTENERS, []):
        listener()

entry.async_on_unload(entry.async_on_state_change(_notify_backup_listeners))

DATA_BACKUP_AGENT_LISTENERS is a key you define yourself, in const.py.

Prepare for a backup

Some integrations need to pause or write their data before a backup, so it can be restored properly. Add these two functions to backup.py, or run python3 -m script.scaffold backup:

Python
from homeassistant.core import HomeAssistant


async def async_pre_backup(hass: HomeAssistant) -> None:
    """Prepare for a backup."""


async def async_post_backup(hass: HomeAssistant) -> None:
    """Resume after a backup."""
Was this page helpful?

Last updated on .