Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The spotify integration."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 from typing import TYPE_CHECKING
7 
8 import aiohttp
9 from spotifyaio import Device, SpotifyClient, SpotifyConnectionError
10 
11 from homeassistant.config_entries import ConfigEntry
12 from homeassistant.const import CONF_ACCESS_TOKEN, Platform
13 from homeassistant.core import HomeAssistant
14 from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
15 from homeassistant.helpers.aiohttp_client import async_get_clientsession
17  OAuth2Session,
18  async_get_config_entry_implementation,
19 )
20 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
21 
22 from .browse_media import async_browse_media
23 from .const import DOMAIN, LOGGER, SPOTIFY_SCOPES
24 from .coordinator import SpotifyConfigEntry, SpotifyCoordinator
25 from .models import SpotifyData
26 from .util import (
27  is_spotify_media_type,
28  resolve_spotify_media_type,
29  spotify_uri_from_media_browser_url,
30 )
31 
32 PLATFORMS = [Platform.MEDIA_PLAYER]
33 
34 __all__ = [
35  "async_browse_media",
36  "DOMAIN",
37  "spotify_uri_from_media_browser_url",
38  "is_spotify_media_type",
39  "resolve_spotify_media_type",
40 ]
41 
42 
43 async def async_setup_entry(hass: HomeAssistant, entry: SpotifyConfigEntry) -> bool:
44  """Set up Spotify from a config entry."""
45  implementation = await async_get_config_entry_implementation(hass, entry)
46  session = OAuth2Session(hass, entry, implementation)
47 
48  try:
49  await session.async_ensure_token_valid()
50  except aiohttp.ClientError as err:
51  raise ConfigEntryNotReady from err
52 
53  spotify = SpotifyClient(async_get_clientsession(hass))
54 
55  spotify.authenticate(session.token[CONF_ACCESS_TOKEN])
56 
57  async def _refresh_token() -> str:
58  await session.async_ensure_token_valid()
59  token = session.token[CONF_ACCESS_TOKEN]
60  if TYPE_CHECKING:
61  assert isinstance(token, str)
62  return token
63 
64  spotify.refresh_token_function = _refresh_token
65 
66  coordinator = SpotifyCoordinator(hass, spotify)
67 
68  await coordinator.async_config_entry_first_refresh()
69 
70  async def _update_devices() -> list[Device]:
71  try:
72  return await spotify.get_devices()
73  except SpotifyConnectionError as err:
74  raise UpdateFailed from err
75 
76  device_coordinator: DataUpdateCoordinator[list[Device]] = DataUpdateCoordinator(
77  hass,
78  LOGGER,
79  name=f"{entry.title} Devices",
80  config_entry=entry,
81  update_interval=timedelta(minutes=5),
82  update_method=_update_devices,
83  )
84  await device_coordinator.async_config_entry_first_refresh()
85 
86  entry.runtime_data = SpotifyData(coordinator, session, device_coordinator)
87 
88  if not set(session.token["scope"].split(" ")).issuperset(SPOTIFY_SCOPES):
89  raise ConfigEntryAuthFailed
90 
91  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
92  return True
93 
94 
95 async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
96  """Unload Spotify config entry."""
97  return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
bool async_setup_entry(HomeAssistant hass, SpotifyConfigEntry entry)
Definition: __init__.py:43
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:95
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)
AbstractOAuth2Implementation async_get_config_entry_implementation(HomeAssistant hass, config_entries.ConfigEntry config_entry)