Small speed up to listing config entries in the websocket api (#108892)

This commit is contained in:
J. Nick Koston 2024-01-25 20:20:19 -10:00 committed by GitHub
parent 9de8409f48
commit dff5e45761
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 16 deletions

View File

@ -516,7 +516,7 @@ async def async_matching_config_entries(
if not type_filter:
return [entry_json(entry) for entry in entries]
integrations = {}
integrations: dict[str, Integration] = {}
# Fetch all the integrations so we can check their type
domains = {entry.domain for entry in entries}
for domain_key, integration_or_exc in (
@ -531,35 +531,32 @@ async def async_matching_config_entries(
# when only helpers are requested, also filter out entries
# from unknown integrations. This prevent them from showing
# up in the helpers UI.
entries = [
entry
filter_is_not_helper = type_filter != ["helper"]
filter_set = set(type_filter)
return [
entry_json(entry)
for entry in entries
if (type_filter != ["helper"] and entry.domain not in integrations)
or (
entry.domain in integrations
and integrations[entry.domain].integration_type in type_filter
# If the filter is not 'helper', we still include the integration
# even if its not returned from async_get_integrations for backwards
# compatibility.
if (
(integration := integrations.get(entry.domain))
and integration.integration_type in filter_set
)
or (filter_is_not_helper and entry.domain not in integrations)
]
return [entry_json(entry) for entry in entries]
@callback
def entry_json(entry: config_entries.ConfigEntry) -> dict[str, Any]:
"""Return JSON value of a config entry."""
handler = config_entries.HANDLERS.get(entry.domain)
# work out if handler has support for options flow
supports_options = handler is not None and handler.async_supports_options_flow(
entry
)
return {
"entry_id": entry.entry_id,
"domain": entry.domain,
"title": entry.title,
"source": entry.source,
"state": entry.state.value,
"supports_options": supports_options,
"supports_options": entry.supports_options,
"supports_remove_device": entry.supports_remove_device or False,
"supports_unload": entry.supports_unload or False,
"pref_disable_new_entities": entry.pref_disable_new_entities,

View File

@ -54,6 +54,7 @@ if TYPE_CHECKING:
from .components.zeroconf import ZeroconfServiceInfo
from .helpers.service_info.mqtt import MqttServiceInfo
_LOGGER = logging.getLogger(__name__)
SOURCE_BLUETOOTH = "bluetooth"
@ -238,6 +239,7 @@ class ConfigEntry:
"_integration_for_domain",
"_tries",
"_setup_again_job",
"_supports_options",
)
def __init__(
@ -318,6 +320,9 @@ class ConfigEntry:
# Supports remove device
self.supports_remove_device: bool | None = None
# Supports options
self._supports_options: bool | None = None
# Listeners to call on update
self.update_listeners: list[UpdateListenerType] = []
@ -351,6 +356,14 @@ class ConfigEntry:
f"title={self.title} state={self.state} unique_id={self.unique_id}>"
)
@property
def supports_options(self) -> bool:
"""Return if entry supports config options."""
if self._supports_options is None and (handler := HANDLERS.get(self.domain)):
# work out if handler has support for options flow
self._supports_options = handler.async_supports_options_flow(self)
return self._supports_options or False
async def async_setup(
self,
hass: HomeAssistant,

View File

@ -734,6 +734,7 @@ async def test_as_dict(snapshot: SnapshotAssertion) -> None:
"_integration_for_domain",
"_tries",
"_setup_again_job",
"_supports_options",
}
entry = MockConfigEntry(entry_id="mock-entry")
@ -1176,6 +1177,7 @@ async def test_create_entry_options(
entries = hass.config_entries.async_entries("comp")
assert len(entries) == 1
assert entries[0].supports_options is False
assert entries[0].data == {"example": "data"}
assert entries[0].options == {"example": "option"}
@ -1202,6 +1204,10 @@ async def test_entry_options(
return OptionsFlowHandler()
def async_supports_options_flow(self, entry: MockConfigEntry) -> bool:
"""Test options flow."""
return True
config_entries.HANDLERS["test"] = TestFlow()
flow = await manager.options.async_create_flow(
entry.entry_id, context={"source": "test"}, data=None
@ -1216,6 +1222,7 @@ async def test_entry_options(
assert entry.data == {"first": True}
assert entry.options == {"second": True}
assert entry.supports_options is True
async def test_entry_options_abort(