Clean up accessing storage.Store helper via hass (#72009)

This commit is contained in:
Franck Nijhof 2022-05-17 18:45:57 +02:00 committed by GitHub
parent c8f700c803
commit 5f44d0f8f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 101 additions and 55 deletions

View File

@ -10,6 +10,7 @@ from typing import Any
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.storage import Store
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from . import models from . import models
@ -45,8 +46,8 @@ class AuthStore:
self._users: dict[str, models.User] | None = None self._users: dict[str, models.User] | None = None
self._groups: dict[str, models.Group] | None = None self._groups: dict[str, models.Group] | None = None
self._perm_lookup: PermissionLookup | None = None self._perm_lookup: PermissionLookup | None = None
self._store = hass.helpers.storage.Store( self._store = Store(
STORAGE_VERSION, STORAGE_KEY, private=True, atomic_writes=True hass, STORAGE_VERSION, STORAGE_KEY, private=True, atomic_writes=True
) )
self._lock = asyncio.Lock() self._lock = asyncio.Lock()
@ -315,7 +316,7 @@ class AuthStore:
self._perm_lookup = perm_lookup = PermissionLookup(ent_reg, dev_reg) self._perm_lookup = perm_lookup = PermissionLookup(ent_reg, dev_reg)
if data is None: if data is None or not isinstance(data, dict):
self._set_defaults() self._set_defaults()
return return

View File

@ -17,6 +17,7 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.data_entry_flow import FlowResult from homeassistant.data_entry_flow import FlowResult
from homeassistant.exceptions import ServiceNotFound from homeassistant.exceptions import ServiceNotFound
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.storage import Store
from . import ( from . import (
MULTI_FACTOR_AUTH_MODULE_SCHEMA, MULTI_FACTOR_AUTH_MODULE_SCHEMA,
@ -99,8 +100,8 @@ class NotifyAuthModule(MultiFactorAuthModule):
"""Initialize the user data store.""" """Initialize the user data store."""
super().__init__(hass, config) super().__init__(hass, config)
self._user_settings: _UsersDict | None = None self._user_settings: _UsersDict | None = None
self._user_store = hass.helpers.storage.Store( self._user_store = Store(
STORAGE_VERSION, STORAGE_KEY, private=True, atomic_writes=True hass, STORAGE_VERSION, STORAGE_KEY, private=True, atomic_writes=True
) )
self._include = config.get(CONF_INCLUDE, []) self._include = config.get(CONF_INCLUDE, [])
self._exclude = config.get(CONF_EXCLUDE, []) self._exclude = config.get(CONF_EXCLUDE, [])
@ -118,7 +119,9 @@ class NotifyAuthModule(MultiFactorAuthModule):
if self._user_settings is not None: if self._user_settings is not None:
return return
if (data := await self._user_store.async_load()) is None: if (data := await self._user_store.async_load()) is None or not isinstance(
data, dict
):
data = {STORAGE_USERS: {}} data = {STORAGE_USERS: {}}
self._user_settings = { self._user_settings = {

View File

@ -10,6 +10,7 @@ import voluptuous as vol
from homeassistant.auth.models import User from homeassistant.auth.models import User
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResult from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.storage import Store
from . import ( from . import (
MULTI_FACTOR_AUTH_MODULE_SCHEMA, MULTI_FACTOR_AUTH_MODULE_SCHEMA,
@ -76,8 +77,8 @@ class TotpAuthModule(MultiFactorAuthModule):
"""Initialize the user data store.""" """Initialize the user data store."""
super().__init__(hass, config) super().__init__(hass, config)
self._users: dict[str, str] | None = None self._users: dict[str, str] | None = None
self._user_store = hass.helpers.storage.Store( self._user_store = Store(
STORAGE_VERSION, STORAGE_KEY, private=True, atomic_writes=True hass, STORAGE_VERSION, STORAGE_KEY, private=True, atomic_writes=True
) )
self._init_lock = asyncio.Lock() self._init_lock = asyncio.Lock()
@ -92,7 +93,9 @@ class TotpAuthModule(MultiFactorAuthModule):
if self._users is not None: if self._users is not None:
return return
if (data := await self._user_store.async_load()) is None: if (data := await self._user_store.async_load()) is None or not isinstance(
data, dict
):
data = {STORAGE_USERS: {}} data = {STORAGE_USERS: {}}
self._users = data.get(STORAGE_USERS, {}) self._users = data.get(STORAGE_USERS, {})

View File

@ -14,6 +14,7 @@ from homeassistant.const import CONF_ID
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.data_entry_flow import FlowResult from homeassistant.data_entry_flow import FlowResult
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.storage import Store
from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
from ..models import Credentials, UserMeta from ..models import Credentials, UserMeta
@ -60,8 +61,8 @@ class Data:
def __init__(self, hass: HomeAssistant) -> None: def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the user data store.""" """Initialize the user data store."""
self.hass = hass self.hass = hass
self._store = hass.helpers.storage.Store( self._store = Store(
STORAGE_VERSION, STORAGE_KEY, private=True, atomic_writes=True hass, STORAGE_VERSION, STORAGE_KEY, private=True, atomic_writes=True
) )
self._data: dict[str, Any] | None = None self._data: dict[str, Any] | None = None
# Legacy mode will allow usernames to start/end with whitespace # Legacy mode will allow usernames to start/end with whitespace
@ -79,7 +80,9 @@ class Data:
async def async_load(self) -> None: async def async_load(self) -> None:
"""Load stored data.""" """Load stored data."""
if (data := await self._store.async_load()) is None: if (data := await self._store.async_load()) is None or not isinstance(
data, dict
):
data = {"users": []} data = {"users": []}
seen: set[str] = set() seen: set[str] = set()
@ -203,7 +206,8 @@ class Data:
async def async_save(self) -> None: async def async_save(self) -> None:
"""Save data.""" """Save data."""
await self._store.async_save(self._data) if self._data is not None:
await self._store.async_save(self._data)
@AUTH_PROVIDERS.register("homeassistant") @AUTH_PROVIDERS.register("homeassistant")

View File

@ -11,6 +11,7 @@ import async_timeout
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers import aiohttp_client from homeassistant.helpers import aiohttp_client
from homeassistant.helpers.storage import Store
from homeassistant.util import dt from homeassistant.util import dt
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -37,7 +38,7 @@ class Auth:
self.client_secret = client_secret self.client_secret = client_secret
self._prefs = None self._prefs = None
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) self._store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
self._get_token_lock = asyncio.Lock() self._get_token_lock = asyncio.Lock()

View File

@ -23,6 +23,7 @@ from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from .const import ( from .const import (
@ -63,7 +64,7 @@ async def async_setup_entry(
"""Set up the Ambiclimate device from config entry.""" """Set up the Ambiclimate device from config entry."""
config = entry.data config = entry.data
websession = async_get_clientsession(hass) websession = async_get_clientsession(hass)
store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
token_info = await store.async_load() token_info = await store.async_load()
oauth = ambiclimate.AmbiclimateOAuth( oauth = ambiclimate.AmbiclimateOAuth(

View File

@ -10,6 +10,7 @@ from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.network import get_url from homeassistant.helpers.network import get_url
from homeassistant.helpers.storage import Store
from .const import ( from .const import (
AUTH_CALLBACK_NAME, AUTH_CALLBACK_NAME,
@ -102,7 +103,7 @@ class AmbiclimateFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
_LOGGER.error("Failed to get access token", exc_info=True) _LOGGER.error("Failed to get access token", exc_info=True)
return None return None
store = self.hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) store = Store(self.hass, STORAGE_VERSION, STORAGE_KEY)
await store.async_save(token_info) await store.async_save(token_info)
return token_info return token_info

View File

@ -71,7 +71,7 @@ class Analytics:
ATTR_ONBOARDED: False, ATTR_ONBOARDED: False,
ATTR_UUID: None, ATTR_UUID: None,
} }
self._store: Store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) self._store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
@property @property
def preferences(self) -> dict: def preferences(self) -> dict:

View File

@ -4,6 +4,7 @@ from __future__ import annotations
from typing import Final from typing import Final
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import UNDEFINED, UndefinedType from homeassistant.helpers.typing import UNDEFINED, UndefinedType
from .const import DOMAIN, PREF_PRELOAD_STREAM from .const import DOMAIN, PREF_PRELOAD_STREAM
@ -35,12 +36,14 @@ class CameraPreferences:
def __init__(self, hass: HomeAssistant) -> None: def __init__(self, hass: HomeAssistant) -> None:
"""Initialize camera prefs.""" """Initialize camera prefs."""
self._hass = hass self._hass = hass
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) self._store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
self._prefs: dict[str, dict[str, bool]] | None = None self._prefs: dict[str, dict[str, bool]] | None = None
async def async_initialize(self) -> None: async def async_initialize(self) -> None:
"""Finish initializing the preferences.""" """Finish initializing the preferences."""
if (prefs := await self._store.async_load()) is None: if (prefs := await self._store.async_load()) is None or not isinstance(
prefs, dict
):
prefs = {} prefs = {}
self._prefs = prefs self._prefs = prefs

View File

@ -5,6 +5,7 @@ from homeassistant.auth.const import GROUP_ID_ADMIN
from homeassistant.auth.models import User from homeassistant.auth.models import User
from homeassistant.components import webhook from homeassistant.components import webhook
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import UNDEFINED from homeassistant.helpers.typing import UNDEFINED
from homeassistant.util.logging import async_create_catching_coro from homeassistant.util.logging import async_create_catching_coro
@ -46,7 +47,7 @@ class CloudPreferences:
def __init__(self, hass): def __init__(self, hass):
"""Initialize cloud prefs.""" """Initialize cloud prefs."""
self._hass = hass self._hass = hass
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) self._store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
self._prefs = None self._prefs = None
self._listeners = [] self._listeners = []

View File

@ -35,6 +35,7 @@ from homeassistant.helpers.dispatcher import (
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import async_call_later from homeassistant.helpers.event import async_call_later
from homeassistant.helpers.service import verify_domain_control from homeassistant.helpers.service import verify_domain_control
from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
@ -198,7 +199,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
user_data = tokens.pop(USER_DATA, None) user_data = tokens.pop(USER_DATA, None)
return (tokens, user_data) return (tokens, user_data)
store = hass.helpers.storage.Store(STORAGE_VER, STORAGE_KEY) store = Store(hass, STORAGE_VER, STORAGE_KEY)
tokens, user_data = await load_auth_tokens(store) tokens, user_data = await load_auth_tokens(store)
client_v2 = evohomeasync2.EvohomeClient( client_v2 = evohomeasync2.EvohomeClient(

View File

@ -18,6 +18,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.storage import Store
from homeassistant.util import slugify from homeassistant.util import slugify
from .const import ( from .const import (
@ -32,7 +33,7 @@ from .const import (
async def get_api(hass: HomeAssistant, host: str) -> Freepybox: async def get_api(hass: HomeAssistant, host: str) -> Freepybox:
"""Get the Freebox API.""" """Get the Freebox API."""
freebox_path = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY).path freebox_path = Store(hass, STORAGE_VERSION, STORAGE_KEY).path
if not os.path.exists(freebox_path): if not os.path.exists(freebox_path):
await hass.async_add_executor_job(os.makedirs, freebox_path) await hass.async_add_executor_job(os.makedirs, freebox_path)

View File

@ -22,6 +22,7 @@ from homeassistant.const import CONF_MODE, CONF_NAME, EVENT_THEMES_UPDATED
from homeassistant.core import HomeAssistant, ServiceCall, callback from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.helpers import service from homeassistant.helpers import service
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.storage import Store
from homeassistant.helpers.translation import async_get_translations from homeassistant.helpers.translation import async_get_translations
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import async_get_integration, bind_hass from homeassistant.loader import async_get_integration, bind_hass
@ -389,11 +390,12 @@ async def _async_setup_themes(
"""Set up themes data and services.""" """Set up themes data and services."""
hass.data[DATA_THEMES] = themes or {} hass.data[DATA_THEMES] = themes or {}
store = hass.data[DATA_THEMES_STORE] = hass.helpers.storage.Store( store = hass.data[DATA_THEMES_STORE] = Store(
THEMES_STORAGE_VERSION, THEMES_STORAGE_KEY hass, THEMES_STORAGE_VERSION, THEMES_STORAGE_KEY
) )
theme_data = await store.async_load() or {} if not (theme_data := await store.async_load()) or not isinstance(theme_data, dict):
theme_data = {}
theme_name = theme_data.get(DATA_DEFAULT_THEME, DEFAULT_THEME) theme_name = theme_data.get(DATA_DEFAULT_THEME, DEFAULT_THEME)
dark_theme_name = theme_data.get(DATA_DEFAULT_DARK_THEME) dark_theme_name = theme_data.get(DATA_DEFAULT_DARK_THEME)

View File

@ -35,8 +35,10 @@ def with_store(orig_func: Callable) -> Callable:
user_id = connection.user.id user_id = connection.user.id
if (store := stores.get(user_id)) is None: if (store := stores.get(user_id)) is None:
store = stores[user_id] = hass.helpers.storage.Store( store = stores[user_id] = Store(
STORAGE_VERSION_USER_DATA, f"frontend.user_data_{connection.user.id}" hass,
STORAGE_VERSION_USER_DATA,
f"frontend.user_data_{connection.user.id}",
) )
if user_id not in data: if user_id not in data:

View File

@ -41,6 +41,7 @@ from homeassistant.helpers.device_registry import (
async_get_registry, async_get_registry,
) )
from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.loader import bind_hass from homeassistant.loader import bind_hass
@ -519,7 +520,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
if not await hassio.is_connected(): if not await hassio.is_connected():
_LOGGER.warning("Not connected with the supervisor / system too busy!") _LOGGER.warning("Not connected with the supervisor / system too busy!")
store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
if (data := await store.async_load()) is None: if (data := await store.async_load()) is None:
data = {} data = {}

View File

@ -17,6 +17,7 @@ from homeassistant.auth.const import GROUP_ID_READ_ONLY
from homeassistant.auth.models import User from homeassistant.auth.models import User
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.storage import Store
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from homeassistant.util.network import is_local from homeassistant.util.network import is_local
@ -108,8 +109,8 @@ def async_user_not_allowed_do_auth(
async def async_setup_auth(hass: HomeAssistant, app: Application) -> None: async def async_setup_auth(hass: HomeAssistant, app: Application) -> None:
"""Create auth middleware for the app.""" """Create auth middleware for the app."""
store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
if (data := await store.async_load()) is None: if (data := await store.async_load()) is None or not isinstance(data, dict):
data = {} data = {}
refresh_token = None refresh_token = None

View File

@ -5,6 +5,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.core import HomeAssistant, ServiceCall
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.storage import Store
from homeassistant.util import slugify from homeassistant.util import slugify
from .account import IcloudAccount from .account import IcloudAccount
@ -81,7 +82,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
if entry.unique_id is None: if entry.unique_id is None:
hass.config_entries.async_update_entry(entry, unique_id=username) hass.config_entries.async_update_entry(entry, unique_id=username)
icloud_dir = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) icloud_dir = Store(hass, STORAGE_VERSION, STORAGE_KEY)
account = IcloudAccount( account = IcloudAccount(
hass, hass,

View File

@ -13,6 +13,7 @@ import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.helpers.storage import Store
from .const import ( from .const import (
CONF_GPS_ACCURACY_THRESHOLD, CONF_GPS_ACCURACY_THRESHOLD,
@ -113,7 +114,7 @@ class IcloudFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
PyiCloudService, PyiCloudService,
self._username, self._username,
self._password, self._password,
self.hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY).path, Store(self.hass, STORAGE_VERSION, STORAGE_KEY).path,
True, True,
None, None,
self._with_family, self._with_family,
@ -162,7 +163,7 @@ class IcloudFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a flow initiated by the user.""" """Handle a flow initiated by the user."""
errors = {} errors = {}
icloud_dir = self.hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) icloud_dir = Store(self.hass, STORAGE_VERSION, STORAGE_KEY)
if not os.path.exists(icloud_dir.path): if not os.path.exists(icloud_dir.path):
await self.hass.async_add_executor_job(os.makedirs, icloud_dir.path) await self.hass.async_add_executor_job(os.makedirs, icloud_dir.path)
@ -276,9 +277,7 @@ class IcloudFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
PyiCloudService, PyiCloudService,
self._username, self._username,
self._password, self._password,
self.hass.helpers.storage.Store( Store(self.hass, STORAGE_VERSION, STORAGE_KEY).path,
STORAGE_VERSION, STORAGE_KEY
).path,
True, True,
None, None,
self._with_family, self._with_family,

View File

@ -10,6 +10,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_DEVICE_ID, CONF_WEBHOOK_ID, Platform from homeassistant.const import ATTR_DEVICE_ID, CONF_WEBHOOK_ID, Platform
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, discovery from homeassistant.helpers import device_registry as dr, discovery
from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from . import websocket_api from . import websocket_api
@ -37,8 +38,10 @@ PLATFORMS = [Platform.SENSOR, Platform.BINARY_SENSOR, Platform.DEVICE_TRACKER]
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the mobile app component.""" """Set up the mobile app component."""
store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
if (app_config := await store.async_load()) is None: if (app_config := await store.async_load()) is None or not isinstance(
app_config, dict
):
app_config = { app_config = {
DATA_CONFIG_ENTRIES: {}, DATA_CONFIG_ENTRIES: {},
DATA_DELETED_IDS: [], DATA_DELETED_IDS: [],

View File

@ -6,6 +6,7 @@ from typing import Any, cast
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.singleton import singleton from homeassistant.helpers.singleton import singleton
from homeassistant.helpers.storage import Store
from .const import ( from .const import (
ATTR_CONFIGURED_ADAPTERS, ATTR_CONFIGURED_ADAPTERS,
@ -37,9 +38,7 @@ class Network:
def __init__(self, hass: HomeAssistant) -> None: def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the Network class.""" """Initialize the Network class."""
self._store = hass.helpers.storage.Store( self._store = Store(hass, STORAGE_VERSION, STORAGE_KEY, atomic_writes=True)
STORAGE_VERSION, STORAGE_KEY, atomic_writes=True
)
self._data: dict[str, Any] = {} self._data: dict[str, Any] = {}
self.adapters: list[Adapter] = [] self.adapters: list[Adapter] = []

View File

@ -32,6 +32,7 @@ from homeassistant.helpers.dispatcher import (
async_dispatcher_send, async_dispatcher_send,
) )
from homeassistant.helpers.network import NoURLAvailableError, get_url from homeassistant.helpers.network import NoURLAvailableError, get_url
from homeassistant.helpers.storage import Store
from .const import ( from .const import (
APP_NAME_PREFIX, APP_NAME_PREFIX,
@ -210,8 +211,8 @@ async def setup_smartapp_endpoint(hass: HomeAssistant):
return return
# Get/create config to store a unique id for this hass instance. # Get/create config to store a unique id for this hass instance.
store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
if not (config := await store.async_load()): if not (config := await store.async_load()) or not isinstance(config, dict):
# Create config # Create config
config = { config = {
CONF_INSTANCE_ID: str(uuid4()), CONF_INSTANCE_ID: str(uuid4()),
@ -282,7 +283,7 @@ async def unload_smartapp_endpoint(hass: HomeAssistant):
if cloudhook_url and cloud.async_is_logged_in(hass): if cloudhook_url and cloud.async_is_logged_in(hass):
await cloud.async_delete_cloudhook(hass, hass.data[DOMAIN][CONF_WEBHOOK_ID]) await cloud.async_delete_cloudhook(hass, hass.data[DOMAIN][CONF_WEBHOOK_ID])
# Remove cloudhook from storage # Remove cloudhook from storage
store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
await store.async_save( await store.async_save(
{ {
CONF_INSTANCE_ID: hass.data[DOMAIN][CONF_INSTANCE_ID], CONF_INSTANCE_ID: hass.data[DOMAIN][CONF_INSTANCE_ID],

View File

@ -4,6 +4,7 @@ from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from .const import ( from .const import (
@ -106,7 +107,7 @@ class UnifiWirelessClients:
"""Set up client storage.""" """Set up client storage."""
self.hass = hass self.hass = hass
self.data = {} self.data = {}
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) self._store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
async def async_load(self): async def async_load(self):
"""Load data from file.""" """Load data from file."""

View File

@ -10,6 +10,7 @@ from typing import cast
import attr import attr
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.storage import Store
from homeassistant.loader import bind_hass from homeassistant.loader import bind_hass
from .typing import ZhaDeviceType from .typing import ZhaDeviceType
@ -38,7 +39,7 @@ class ZhaStorage:
"""Initialize the zha device storage.""" """Initialize the zha device storage."""
self.hass: HomeAssistant = hass self.hass: HomeAssistant = hass
self.devices: MutableMapping[str, ZhaDeviceEntry] = {} self.devices: MutableMapping[str, ZhaDeviceEntry] = {}
self._store = hass.helpers.storage.Store(STORAGE_VERSION, STORAGE_KEY) self._store = Store(hass, STORAGE_VERSION, STORAGE_KEY)
@callback @callback
def async_create_device(self, device: ZhaDeviceType) -> ZhaDeviceEntry: def async_create_device(self, device: ZhaDeviceType) -> ZhaDeviceEntry:

View File

@ -1895,11 +1895,19 @@ class Config:
async def async_load(self) -> None: async def async_load(self) -> None:
"""Load [homeassistant] core config.""" """Load [homeassistant] core config."""
store = self.hass.helpers.storage.Store( # Circular dep
CORE_STORAGE_VERSION, CORE_STORAGE_KEY, private=True, atomic_writes=True # pylint: disable=import-outside-toplevel
from .helpers.storage import Store
store = Store(
self.hass,
CORE_STORAGE_VERSION,
CORE_STORAGE_KEY,
private=True,
atomic_writes=True,
) )
if not (data := await store.async_load()): if not (data := await store.async_load()) or not isinstance(data, dict):
return return
# In 2021.9 we fixed validation to disallow a path (because that's never correct) # In 2021.9 we fixed validation to disallow a path (because that's never correct)
@ -1931,6 +1939,10 @@ class Config:
async def async_store(self) -> None: async def async_store(self) -> None:
"""Store [homeassistant] core config.""" """Store [homeassistant] core config."""
# Circular dep
# pylint: disable=import-outside-toplevel
from .helpers.storage import Store
data = { data = {
"latitude": self.latitude, "latitude": self.latitude,
"longitude": self.longitude, "longitude": self.longitude,
@ -1943,7 +1955,11 @@ class Config:
"currency": self.currency, "currency": self.currency,
} }
store = self.hass.helpers.storage.Store( store = Store(
CORE_STORAGE_VERSION, CORE_STORAGE_KEY, private=True, atomic_writes=True self.hass,
CORE_STORAGE_VERSION,
CORE_STORAGE_KEY,
private=True,
atomic_writes=True,
) )
await store.async_save(data) await store.async_save(data)

View File

@ -12,6 +12,7 @@ from homeassistant.loader import bind_hass
from homeassistant.util import slugify from homeassistant.util import slugify
from . import device_registry as dr, entity_registry as er from . import device_registry as dr, entity_registry as er
from .storage import Store
from .typing import UNDEFINED, UndefinedType from .typing import UNDEFINED, UndefinedType
DATA_REGISTRY = "area_registry" DATA_REGISTRY = "area_registry"
@ -47,9 +48,7 @@ class AreaRegistry:
"""Initialize the area registry.""" """Initialize the area registry."""
self.hass = hass self.hass = hass
self.areas: MutableMapping[str, AreaEntry] = {} self.areas: MutableMapping[str, AreaEntry] = {}
self._store = hass.helpers.storage.Store( self._store = Store(hass, STORAGE_VERSION, STORAGE_KEY, atomic_writes=True)
STORAGE_VERSION, STORAGE_KEY, atomic_writes=True
)
self._normalized_name_area_idx: dict[str, str] = {} self._normalized_name_area_idx: dict[str, str] = {}
@callback @callback
@ -176,7 +175,7 @@ class AreaRegistry:
areas: MutableMapping[str, AreaEntry] = OrderedDict() areas: MutableMapping[str, AreaEntry] = OrderedDict()
if data is not None: if isinstance(data, dict):
for area in data["areas"]: for area in data["areas"]:
normalized_name = normalize_area_name(area["name"]) normalized_name = normalize_area_name(area["name"])
areas[area["id"]] = AreaEntry( areas[area["id"]] = AreaEntry(