Skip to content

Commit

Permalink
Replace flake8 with ruff (#925)
Browse files Browse the repository at this point in the history
  • Loading branch information
KapJI authored Nov 6, 2024
1 parent ff6a4c1 commit 8852430
Show file tree
Hide file tree
Showing 13 changed files with 324 additions and 194 deletions.
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ repos:
language: system
types: [python]
require_serial: true
- id: mypy
name: mypy
entry: poetry run mypy
- id: ruff-check
name: ruff check
entry: poetry run ruff check --fix
language: system
types: [python]
require_serial: true
- id: flake8
name: flake8
entry: poetry run flake8
- id: mypy
name: mypy
entry: poetry run mypy
language: system
types: [python]
require_serial: true
Expand Down
9 changes: 5 additions & 4 deletions custom_components/google_home/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
"""
Custom integration to integrate Google Home with Home Assistant.
"""Custom integration to integrate Google Home with Home Assistant.
For more details about this integration, please refer to
https://github.com/leikoilja/ha-google-home
"""

from datetime import timedelta
import logging
from typing import cast
from typing import TYPE_CHECKING, cast

from homeassistant.components import zeroconf
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
Expand All @@ -28,9 +27,11 @@
STARTUP_MESSAGE,
UPDATE_INTERVAL,
)
from .models import GoogleHomeDevice
from .types import GoogleHomeConfigEntry

if TYPE_CHECKING:
from .models import GoogleHomeDevice

_LOGGER: logging.Logger = logging.getLogger(__package__)


Expand Down
62 changes: 33 additions & 29 deletions custom_components/google_home/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@
from http import HTTPStatus
import ipaddress
import logging
from typing import Literal, cast
from typing import TYPE_CHECKING, Literal, cast

from aiohttp import ClientError, ClientSession, ClientTimeout
from aiohttp.client_exceptions import ClientConnectorError, ContentTypeError
from glocaltokens.client import Device, GLocalAuthenticationTokens
from glocaltokens.utils.token import is_aas_et
from zeroconf import Zeroconf

from homeassistant.core import HomeAssistant

from .const import (
API_ENDPOINT_ALARM_DELETE,
Expand All @@ -35,11 +32,16 @@
from .models import GoogleHomeDevice
from .types import AlarmJsonDict, JsonDict, TimerJsonDict

if TYPE_CHECKING:
from zeroconf import Zeroconf

from homeassistant.core import HomeAssistant

_LOGGER: logging.Logger = logging.getLogger(__package__)


class GlocaltokensApiClient:
"""API client"""
"""API client."""

def __init__(
self,
Expand Down Expand Up @@ -69,7 +71,7 @@ def __init__(
self.zeroconf_instance = zeroconf_instance

async def async_get_master_token(self) -> str:
"""Get master API token"""
"""Get master API token."""

def _get_master_token() -> str | None:
return self._client.get_master_token()
Expand All @@ -80,7 +82,7 @@ def _get_master_token() -> str | None:
return master_token

async def async_get_access_token(self) -> str:
"""Get access token using master token"""
"""Get access token using master token."""

def _get_access_token() -> str | None:
return self._client.get_access_token()
Expand All @@ -92,7 +94,9 @@ def _get_access_token() -> str | None:

async def get_google_devices(self) -> list[GoogleHomeDevice]:
"""Get google device authentication tokens.
Note this method will fetch necessary access tokens if missing"""
Note this method will fetch necessary access tokens if missing.
"""

if not self.google_devices:

Expand All @@ -116,7 +120,7 @@ def _get_google_devices() -> list[Device]:
return self.google_devices

async def get_android_id(self) -> str:
"""Generate random android_id"""
"""Generate random android_id."""

def _get_android_id() -> str:
return self._client.get_android_id()
Expand All @@ -125,15 +129,16 @@ def _get_android_id() -> str:

@staticmethod
def create_url(ip_address: str, port: int, api_endpoint: str) -> str:
"""Creates url to endpoint.
Note: port argument is unused because all request must be done to 8443"""
"""Create url to endpoint.
Note: port argument is unused because all request must be done to 8443.
"""
if isinstance(ipaddress.ip_address(ip_address), ipaddress.IPv6Address):
ip_address = f"[{ip_address}]"
return f"https://{ip_address}:{port}/{api_endpoint}"

async def update_google_devices_information(self) -> list[GoogleHomeDevice]:
"""Retrieves devices from glocaltokens and
fetches alarm/timer data from each of the device"""
"""Retrieve devices from glocaltokens and fetches alarm/timer data from each of the device."""

devices = await self.get_google_devices()

Expand All @@ -151,28 +156,26 @@ async def update_google_devices_information(self) -> list[GoogleHomeDevice]:
device.name,
)

coordinator_data = await asyncio.gather(
return await asyncio.gather(
*[
self.collect_data_from_endpoints(device)
for device in devices
if device.ip_address and device.auth_token
]
)
return coordinator_data

async def collect_data_from_endpoints(
self, device: GoogleHomeDevice
) -> GoogleHomeDevice:
"""Collect data from different endpoints."""
device = await self.update_alarms_and_timers(device)
device = await self.update_alarm_volume(device)
device = await self.update_do_not_disturb(device)
return device
return await self.update_do_not_disturb(device)

async def update_alarms_and_timers(
self, device: GoogleHomeDevice
) -> GoogleHomeDevice:
"""Fetches timers and alarms from google device"""
"""Fetch timers and alarms from google device."""
response = await self.request(
method="GET", endpoint=API_ENDPOINT_ALARMS, device=device, polling=True
)
Expand Down Expand Up @@ -201,8 +204,10 @@ async def update_alarms_and_timers(
async def delete_alarm_or_timer(
self, device: GoogleHomeDevice, item_to_delete: str
) -> None:
"""Deletes a timer or alarm.
Can also delete multiple if a list is provided (Not implemented yet)."""
"""Delete a timer or alarm.
Can also delete multiple if a list is provided (Not implemented yet).
"""

data = {"ids": [item_to_delete]}

Expand Down Expand Up @@ -247,7 +252,7 @@ async def delete_alarm_or_timer(
)

async def reboot_google_device(self, device: GoogleHomeDevice) -> None:
"""Reboots a Google Home device if it supports this."""
"""Reboot a Google Home device if it supports this."""

# "now" means reboot and "fdr" means factory reset (Not implemented).
data = {"params": "now"}
Expand All @@ -271,7 +276,7 @@ async def reboot_google_device(self, device: GoogleHomeDevice) -> None:
async def update_do_not_disturb(
self, device: GoogleHomeDevice, enable: bool | None = None
) -> GoogleHomeDevice:
"""Gets or sets the do not disturb setting on a Google Home device."""
"""Get or set the do not disturb setting on a Google Home device."""

data = None
polling = False
Expand Down Expand Up @@ -324,7 +329,7 @@ async def update_do_not_disturb(
async def update_alarm_volume(
self, device: GoogleHomeDevice, volume: int | None = None
) -> GoogleHomeDevice:
"""Gets or sets the alarm volume setting on a Google Home device."""
"""Get or set the alarm volume setting on a Google Home device."""

data: JsonDict | None = None
polling = False
Expand Down Expand Up @@ -394,7 +399,7 @@ async def request(
data: JsonDict | None = None,
polling: bool = False,
) -> JsonDict | None:
"""Shared request method"""
"""Shared request method."""

if device.ip_address is None:
_LOGGER.warning("Device %s doesn't have an IP address!", device.name)
Expand Down Expand Up @@ -479,15 +484,14 @@ async def request(
device.name,
)
device.available = False
except ClientError as ex:
except ClientError:
# Make sure that we log the exception from the client if one occurred.
_LOGGER.error(
"Request from %s device error: %s",
_LOGGER.exception(
"Request from %s device error",
device.name,
ex,
)
device.available = False
except asyncio.TimeoutError:
except TimeoutError:
_LOGGER.debug(
"%s device timed out while performing a request to it - Raw data: %s",
device.name,
Expand Down
46 changes: 24 additions & 22 deletions custom_components/google_home/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""Adds config flow for Google Home"""
"""Adds config flow for Google Home."""

from __future__ import annotations

from datetime import timedelta
import logging
from typing import Self
from typing import TYPE_CHECKING, Self

from requests.exceptions import RequestException
import voluptuous as vol
Expand All @@ -27,7 +27,9 @@
UPDATE_INTERVAL,
)
from .exceptions import InvalidMasterToken
from .types import ConfigFlowDict, GoogleHomeConfigEntry, OptionsFlowDict

if TYPE_CHECKING:
from .types import ConfigFlowDict, GoogleHomeConfigEntry, OptionsFlowDict

_LOGGER: logging.Logger = logging.getLogger(__package__)

Expand Down Expand Up @@ -81,20 +83,19 @@ async def async_step_user(
title = f"{MANUFACTURER} (master_token)"
else:
self._errors["base"] = "master-token-invalid"
# master_token not provided, so use username/password authentication
elif len(password) < MAX_PASSWORD_LENGTH:
client = GlocaltokensApiClient(
hass=self.hass,
session=session,
username=username,
password=password,
)
master_token = await self._get_master_token(client)
if not master_token:
self._errors["base"] = "auth"
else:
# master_token not provided, so use username/password authentication
if len(password) < MAX_PASSWORD_LENGTH:
client = GlocaltokensApiClient(
hass=self.hass,
session=session,
username=username,
password=password,
)
master_token = await self._get_master_token(client)
if not master_token:
self._errors["base"] = "auth"
else:
self._errors["base"] = "pass-len"
self._errors["base"] = "pass-len"

if client and not self._errors:
config_data: dict[str, str] = {}
Expand All @@ -112,6 +113,7 @@ async def async_step_user(
def async_get_options_flow(
config_entry: GoogleHomeConfigEntry,
) -> GoogleHomeOptionsFlowHandler:
"""Handle options flow."""
return GoogleHomeOptionsFlowHandler(config_entry)

async def _show_config_form(self) -> ConfigFlowResult:
Expand All @@ -130,22 +132,22 @@ async def _show_config_form(self) -> ConfigFlowResult:

@staticmethod
async def _get_master_token(client: GlocaltokensApiClient) -> str:
"""Returns master token if credentials are valid."""
"""Return master token if credentials are valid."""
master_token = ""
try:
master_token = await client.async_get_master_token()
except (InvalidMasterToken, RequestException) as exception:
_LOGGER.error(exception)
except (InvalidMasterToken, RequestException):
_LOGGER.exception("Failed to get master token")
return master_token

@staticmethod
async def _get_access_token(client: GlocaltokensApiClient) -> str:
"""Returns access token if master token is valid."""
"""Return access token if master token is valid."""
access_token = ""
try:
access_token = await client.async_get_access_token()
except (InvalidMasterToken, RequestException) as exception:
_LOGGER.error(exception)
except (InvalidMasterToken, RequestException):
_LOGGER.exception("Failed to get access token")
return access_token


Expand Down
17 changes: 11 additions & 6 deletions custom_components/google_home/entity.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
"""Defines base entities for Google Home"""
"""Defines base entities for Google Home."""

from __future__ import annotations

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING

from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)

from .api import GlocaltokensApiClient
from .const import DEFAULT_NAME, DOMAIN, MANUFACTURER
from .models import GoogleHomeDevice

if TYPE_CHECKING:
from homeassistant.helpers.device_registry import DeviceInfo

from .api import GlocaltokensApiClient


class GoogleHomeBaseEntity(
CoordinatorEntity[DataUpdateCoordinator[list[GoogleHomeDevice]]], ABC
):
"""Base entity base for Google Home sensors"""
"""Base entity base for Google Home sensors."""

def __init__(
self,
Expand All @@ -28,6 +32,7 @@ def __init__(
device_name: str,
device_model: str,
):
"""Create Google Home base entity."""
super().__init__(coordinator)
self.client = client
self.device_id = device_id
Expand All @@ -51,6 +56,7 @@ def unique_id(self) -> str: # type: ignore[override]

@property
def device_info(self) -> DeviceInfo | None: # type: ignore[override]
"""Return device info."""
return {
"identifiers": {(DOMAIN, self.device_id)},
"name": f"{DEFAULT_NAME} {self.device_name}",
Expand All @@ -59,8 +65,7 @@ def device_info(self) -> DeviceInfo | None: # type: ignore[override]
}

def get_device(self) -> GoogleHomeDevice | None:
"""Return the device matched by device name
from the list of google devices in coordinator_data"""
"""Return the device matched by device name from the list of google devices in coordinator_data."""
matched_devices: list[GoogleHomeDevice] = [
device
for device in self.coordinator.data
Expand Down
Loading

0 comments on commit 8852430

Please sign in to comment.