Use generics in NextDNS (#74517)

Use generics in nextdns
This commit is contained in:
epenet 2022-07-07 09:22:35 +02:00 committed by GitHub
parent 4a4dabaaa5
commit 46f2abc38c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 15 deletions

View File

@ -4,6 +4,7 @@ from __future__ import annotations
import asyncio import asyncio
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import TypeVar
from aiohttp.client_exceptions import ClientConnectorError from aiohttp.client_exceptions import ClientConnectorError
from async_timeout import timeout from async_timeout import timeout
@ -39,8 +40,10 @@ from .const import (
UPDATE_INTERVAL_ANALYTICS, UPDATE_INTERVAL_ANALYTICS,
) )
TCoordinatorData = TypeVar("TCoordinatorData", bound=NextDnsData)
class NextDnsUpdateCoordinator(DataUpdateCoordinator):
class NextDnsUpdateCoordinator(DataUpdateCoordinator[TCoordinatorData]):
"""Class to manage fetching NextDNS data API.""" """Class to manage fetching NextDNS data API."""
def __init__( def __init__(
@ -64,12 +67,12 @@ class NextDnsUpdateCoordinator(DataUpdateCoordinator):
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval) super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
async def _async_update_data(self) -> NextDnsData: async def _async_update_data(self) -> TCoordinatorData:
"""Update data via library.""" """Update data via library."""
raise NotImplementedError("Update method not implemented") raise NotImplementedError("Update method not implemented")
class NextDnsStatusUpdateCoordinator(NextDnsUpdateCoordinator): class NextDnsStatusUpdateCoordinator(NextDnsUpdateCoordinator[AnalyticsStatus]):
"""Class to manage fetching NextDNS analytics status data from API.""" """Class to manage fetching NextDNS analytics status data from API."""
async def _async_update_data(self) -> AnalyticsStatus: async def _async_update_data(self) -> AnalyticsStatus:
@ -81,7 +84,7 @@ class NextDnsStatusUpdateCoordinator(NextDnsUpdateCoordinator):
raise UpdateFailed(err) from err raise UpdateFailed(err) from err
class NextDnsDnssecUpdateCoordinator(NextDnsUpdateCoordinator): class NextDnsDnssecUpdateCoordinator(NextDnsUpdateCoordinator[AnalyticsDnssec]):
"""Class to manage fetching NextDNS analytics Dnssec data from API.""" """Class to manage fetching NextDNS analytics Dnssec data from API."""
async def _async_update_data(self) -> AnalyticsDnssec: async def _async_update_data(self) -> AnalyticsDnssec:
@ -93,7 +96,7 @@ class NextDnsDnssecUpdateCoordinator(NextDnsUpdateCoordinator):
raise UpdateFailed(err) from err raise UpdateFailed(err) from err
class NextDnsEncryptionUpdateCoordinator(NextDnsUpdateCoordinator): class NextDnsEncryptionUpdateCoordinator(NextDnsUpdateCoordinator[AnalyticsEncryption]):
"""Class to manage fetching NextDNS analytics encryption data from API.""" """Class to manage fetching NextDNS analytics encryption data from API."""
async def _async_update_data(self) -> AnalyticsEncryption: async def _async_update_data(self) -> AnalyticsEncryption:
@ -105,7 +108,7 @@ class NextDnsEncryptionUpdateCoordinator(NextDnsUpdateCoordinator):
raise UpdateFailed(err) from err raise UpdateFailed(err) from err
class NextDnsIpVersionsUpdateCoordinator(NextDnsUpdateCoordinator): class NextDnsIpVersionsUpdateCoordinator(NextDnsUpdateCoordinator[AnalyticsIpVersions]):
"""Class to manage fetching NextDNS analytics IP versions data from API.""" """Class to manage fetching NextDNS analytics IP versions data from API."""
async def _async_update_data(self) -> AnalyticsIpVersions: async def _async_update_data(self) -> AnalyticsIpVersions:
@ -117,7 +120,7 @@ class NextDnsIpVersionsUpdateCoordinator(NextDnsUpdateCoordinator):
raise UpdateFailed(err) from err raise UpdateFailed(err) from err
class NextDnsProtocolsUpdateCoordinator(NextDnsUpdateCoordinator): class NextDnsProtocolsUpdateCoordinator(NextDnsUpdateCoordinator[AnalyticsProtocols]):
"""Class to manage fetching NextDNS analytics protocols data from API.""" """Class to manage fetching NextDNS analytics protocols data from API."""
async def _async_update_data(self) -> AnalyticsProtocols: async def _async_update_data(self) -> AnalyticsProtocols:

View File

@ -3,7 +3,15 @@ from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, cast from typing import Generic, cast
from nextdns import (
AnalyticsDnssec,
AnalyticsEncryption,
AnalyticsIpVersions,
AnalyticsProtocols,
AnalyticsStatus,
)
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorEntity, SensorEntity,
@ -18,7 +26,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import NextDnsUpdateCoordinator from . import NextDnsUpdateCoordinator, TCoordinatorData
from .const import ( from .const import (
ATTR_DNSSEC, ATTR_DNSSEC,
ATTR_ENCRYPTION, ATTR_ENCRYPTION,
@ -32,23 +40,26 @@ PARALLEL_UPDATES = 1
@dataclass @dataclass
class NextDnsSensorRequiredKeysMixin: class NextDnsSensorRequiredKeysMixin(Generic[TCoordinatorData]):
"""Class for NextDNS entity required keys.""" """Class for NextDNS entity required keys."""
coordinator_class: type[TCoordinatorData]
coordinator_type: str coordinator_type: str
value: Callable[[Any], StateType] value: Callable[[TCoordinatorData], StateType]
@dataclass @dataclass
class NextDnsSensorEntityDescription( class NextDnsSensorEntityDescription(
SensorEntityDescription, NextDnsSensorRequiredKeysMixin SensorEntityDescription,
NextDnsSensorRequiredKeysMixin[TCoordinatorData],
): ):
"""NextDNS sensor entity description.""" """NextDNS sensor entity description."""
SENSORS = ( SENSORS: tuple[NextDnsSensorEntityDescription, ...] = (
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="all_queries", key="all_queries",
coordinator_class=AnalyticsStatus,
coordinator_type=ATTR_STATUS, coordinator_type=ATTR_STATUS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:dns", icon="mdi:dns",
@ -59,6 +70,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="blocked_queries", key="blocked_queries",
coordinator_class=AnalyticsStatus,
coordinator_type=ATTR_STATUS, coordinator_type=ATTR_STATUS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:dns", icon="mdi:dns",
@ -69,6 +81,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="relayed_queries", key="relayed_queries",
coordinator_class=AnalyticsStatus,
coordinator_type=ATTR_STATUS, coordinator_type=ATTR_STATUS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:dns", icon="mdi:dns",
@ -79,6 +92,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="blocked_queries_ratio", key="blocked_queries_ratio",
coordinator_class=AnalyticsStatus,
coordinator_type=ATTR_STATUS, coordinator_type=ATTR_STATUS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:dns", icon="mdi:dns",
@ -89,6 +103,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="doh_queries", key="doh_queries",
coordinator_class=AnalyticsProtocols,
coordinator_type=ATTR_PROTOCOLS, coordinator_type=ATTR_PROTOCOLS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -100,6 +115,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="dot_queries", key="dot_queries",
coordinator_class=AnalyticsProtocols,
coordinator_type=ATTR_PROTOCOLS, coordinator_type=ATTR_PROTOCOLS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -111,6 +127,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="doq_queries", key="doq_queries",
coordinator_class=AnalyticsProtocols,
coordinator_type=ATTR_PROTOCOLS, coordinator_type=ATTR_PROTOCOLS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -122,6 +139,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="udp_queries", key="udp_queries",
coordinator_class=AnalyticsProtocols,
coordinator_type=ATTR_PROTOCOLS, coordinator_type=ATTR_PROTOCOLS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -133,6 +151,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="doh_queries_ratio", key="doh_queries_ratio",
coordinator_class=AnalyticsProtocols,
coordinator_type=ATTR_PROTOCOLS, coordinator_type=ATTR_PROTOCOLS,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
icon="mdi:dns", icon="mdi:dns",
@ -144,6 +163,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="dot_queries_ratio", key="dot_queries_ratio",
coordinator_class=AnalyticsProtocols,
coordinator_type=ATTR_PROTOCOLS, coordinator_type=ATTR_PROTOCOLS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -155,6 +175,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="doq_queries_ratio", key="doq_queries_ratio",
coordinator_class=AnalyticsProtocols,
coordinator_type=ATTR_PROTOCOLS, coordinator_type=ATTR_PROTOCOLS,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
icon="mdi:dns", icon="mdi:dns",
@ -166,6 +187,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="udp_queries_ratio", key="udp_queries_ratio",
coordinator_class=AnalyticsProtocols,
coordinator_type=ATTR_PROTOCOLS, coordinator_type=ATTR_PROTOCOLS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -177,6 +199,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="encrypted_queries", key="encrypted_queries",
coordinator_class=AnalyticsEncryption,
coordinator_type=ATTR_ENCRYPTION, coordinator_type=ATTR_ENCRYPTION,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -188,6 +211,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="unencrypted_queries", key="unencrypted_queries",
coordinator_class=AnalyticsEncryption,
coordinator_type=ATTR_ENCRYPTION, coordinator_type=ATTR_ENCRYPTION,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -199,6 +223,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="encrypted_queries_ratio", key="encrypted_queries_ratio",
coordinator_class=AnalyticsEncryption,
coordinator_type=ATTR_ENCRYPTION, coordinator_type=ATTR_ENCRYPTION,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -210,6 +235,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="ipv4_queries", key="ipv4_queries",
coordinator_class=AnalyticsIpVersions,
coordinator_type=ATTR_IP_VERSIONS, coordinator_type=ATTR_IP_VERSIONS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -221,6 +247,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="ipv6_queries", key="ipv6_queries",
coordinator_class=AnalyticsIpVersions,
coordinator_type=ATTR_IP_VERSIONS, coordinator_type=ATTR_IP_VERSIONS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -232,6 +259,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="ipv6_queries_ratio", key="ipv6_queries_ratio",
coordinator_class=AnalyticsIpVersions,
coordinator_type=ATTR_IP_VERSIONS, coordinator_type=ATTR_IP_VERSIONS,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -243,6 +271,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="validated_queries", key="validated_queries",
coordinator_class=AnalyticsDnssec,
coordinator_type=ATTR_DNSSEC, coordinator_type=ATTR_DNSSEC,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -254,6 +283,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="not_validated_queries", key="not_validated_queries",
coordinator_class=AnalyticsDnssec,
coordinator_type=ATTR_DNSSEC, coordinator_type=ATTR_DNSSEC,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -265,6 +295,7 @@ SENSORS = (
), ),
NextDnsSensorEntityDescription( NextDnsSensorEntityDescription(
key="validated_queries_ratio", key="validated_queries_ratio",
coordinator_class=AnalyticsDnssec,
coordinator_type=ATTR_DNSSEC, coordinator_type=ATTR_DNSSEC,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
@ -294,12 +325,14 @@ async def async_setup_entry(
async_add_entities(sensors) async_add_entities(sensors)
class NextDnsSensor(CoordinatorEntity[NextDnsUpdateCoordinator], SensorEntity): class NextDnsSensor(
CoordinatorEntity[NextDnsUpdateCoordinator[TCoordinatorData]], SensorEntity
):
"""Define an NextDNS sensor.""" """Define an NextDNS sensor."""
def __init__( def __init__(
self, self,
coordinator: NextDnsUpdateCoordinator, coordinator: NextDnsUpdateCoordinator[TCoordinatorData],
description: NextDnsSensorEntityDescription, description: NextDnsSensorEntityDescription,
) -> None: ) -> None:
"""Initialize.""" """Initialize."""