Add mypy checks
This commit is contained in:
		
							
								
								
									
										6
									
								
								.github/workflows/python-check.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/python-check.yml
									
									
									
									
										vendored
									
									
								
							@@ -25,12 +25,16 @@ jobs:
 | 
				
			|||||||
      run: |
 | 
					      run: |
 | 
				
			||||||
        python -m pip install --upgrade pip
 | 
					        python -m pip install --upgrade pip
 | 
				
			||||||
        python -m pip install -r requirements.txt
 | 
					        python -m pip install -r requirements.txt
 | 
				
			||||||
        python -m pip install flake8 pylint black
 | 
					        python -m pip install flake8 pylint black mypy
 | 
				
			||||||
    - name: Lint with flake8
 | 
					    - name: Lint with flake8
 | 
				
			||||||
      run: |
 | 
					      run: |
 | 
				
			||||||
        # stop the build if there are Python syntax errors or undefined names
 | 
					        # stop the build if there are Python syntax errors or undefined names
 | 
				
			||||||
        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
 | 
					        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
 | 
				
			||||||
        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics
 | 
					        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics
 | 
				
			||||||
 | 
					    - name: Type check with mypy
 | 
				
			||||||
 | 
					      run: |
 | 
				
			||||||
 | 
					        # stop the build if there are Python syntax errors or undefined names
 | 
				
			||||||
 | 
					        mypy pyhon/
 | 
				
			||||||
    # - name: Analysing the code with pylint
 | 
					    # - name: Analysing the code with pylint
 | 
				
			||||||
    #   run: |
 | 
					    #   run: |
 | 
				
			||||||
    #     pylint --max-line-length 88 $(git ls-files '*.py')
 | 
					    #     pylint --max-line-length 88 $(git ls-files '*.py')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,23 +1,29 @@
 | 
				
			|||||||
import importlib
 | 
					import importlib
 | 
				
			||||||
from contextlib import suppress
 | 
					from contextlib import suppress
 | 
				
			||||||
from typing import Optional, Dict
 | 
					from typing import Optional, Dict, Any
 | 
				
			||||||
 | 
					from typing import TYPE_CHECKING
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon import helper
 | 
					from pyhon import helper
 | 
				
			||||||
from pyhon.commands import HonCommand
 | 
					from pyhon.commands import HonCommand
 | 
				
			||||||
from pyhon.parameter import HonParameterFixed
 | 
					from pyhon.parameter import HonParameterFixed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if TYPE_CHECKING:
 | 
				
			||||||
 | 
					    from pyhon import HonAPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonAppliance:
 | 
					class HonAppliance:
 | 
				
			||||||
    def __init__(self, api, info: Dict, zone: int = 0) -> None:
 | 
					    def __init__(
 | 
				
			||||||
 | 
					        self, api: Optional["HonAPI"], info: Dict[str, Any], zone: int = 0
 | 
				
			||||||
 | 
					    ) -> None:
 | 
				
			||||||
        if attributes := info.get("attributes"):
 | 
					        if attributes := info.get("attributes"):
 | 
				
			||||||
            info["attributes"] = {v["parName"]: v["parValue"] for v in attributes}
 | 
					            info["attributes"] = {v["parName"]: v["parValue"] for v in attributes}
 | 
				
			||||||
        self._info = info
 | 
					        self._info: Dict = info
 | 
				
			||||||
        self._api = api
 | 
					        self._api: Optional[HonAPI] = api
 | 
				
			||||||
        self._appliance_model = {}
 | 
					        self._appliance_model: Dict = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._commands = {}
 | 
					        self._commands: Dict = {}
 | 
				
			||||||
        self._statistics = {}
 | 
					        self._statistics: Dict = {}
 | 
				
			||||||
        self._attributes = {}
 | 
					        self._attributes: Dict = {}
 | 
				
			||||||
        self._zone = zone
 | 
					        self._zone = zone
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
@@ -58,11 +64,11 @@ class HonAppliance:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def appliance_model_id(self) -> str:
 | 
					    def appliance_model_id(self) -> str:
 | 
				
			||||||
        return self._info.get("applianceModelId")
 | 
					        return self._info.get("applianceModelId", "")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def appliance_type(self) -> str:
 | 
					    def appliance_type(self) -> str:
 | 
				
			||||||
        return self._info.get("applianceTypeName")
 | 
					        return self._info.get("applianceTypeName", "")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def mac_address(self) -> str:
 | 
					    def mac_address(self) -> str:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,11 @@ import logging
 | 
				
			|||||||
import re
 | 
					import re
 | 
				
			||||||
import secrets
 | 
					import secrets
 | 
				
			||||||
import urllib
 | 
					import urllib
 | 
				
			||||||
 | 
					from contextlib import suppress
 | 
				
			||||||
from dataclasses import dataclass
 | 
					from dataclasses import dataclass
 | 
				
			||||||
from datetime import datetime, timedelta
 | 
					from datetime import datetime, timedelta
 | 
				
			||||||
from pprint import pformat
 | 
					from pprint import pformat
 | 
				
			||||||
from typing import Dict, Optional
 | 
					from typing import Dict, Optional, List
 | 
				
			||||||
from urllib import parse
 | 
					from urllib import parse
 | 
				
			||||||
from urllib.parse import quote
 | 
					from urllib.parse import quote
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -82,14 +83,15 @@ class HonAuth:
 | 
				
			|||||||
        if fail:
 | 
					        if fail:
 | 
				
			||||||
            raise exceptions.HonAuthenticationError("Can't login")
 | 
					            raise exceptions.HonAuthenticationError("Can't login")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _generate_nonce(self) -> str:
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def _generate_nonce() -> str:
 | 
				
			||||||
        nonce = secrets.token_hex(16)
 | 
					        nonce = secrets.token_hex(16)
 | 
				
			||||||
        return f"{nonce[:8]}-{nonce[8:12]}-{nonce[12:16]}-{nonce[16:20]}-{nonce[20:]}"
 | 
					        return f"{nonce[:8]}-{nonce[8:12]}-{nonce[12:16]}-{nonce[16:20]}-{nonce[20:]}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _load_login(self):
 | 
					    async def _load_login(self) -> bool:
 | 
				
			||||||
        login_url = await self._introduce()
 | 
					        login_url = await self._introduce()
 | 
				
			||||||
        login_url = await self._handle_redirects(login_url)
 | 
					        login_url = await self._handle_redirects(login_url)
 | 
				
			||||||
        await self._login_url(login_url)
 | 
					        return await self._login_url(login_url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _introduce(self) -> str:
 | 
					    async def _introduce(self) -> str:
 | 
				
			||||||
        redirect_uri = urllib.parse.quote(f"{const.APP}://mobilesdk/detect/oauth/done")
 | 
					        redirect_uri = urllib.parse.quote(f"{const.APP}://mobilesdk/detect/oauth/done")
 | 
				
			||||||
@@ -101,8 +103,8 @@ class HonAuth:
 | 
				
			|||||||
            "scope": "api openid refresh_token web",
 | 
					            "scope": "api openid refresh_token web",
 | 
				
			||||||
            "nonce": self._generate_nonce(),
 | 
					            "nonce": self._generate_nonce(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        params = "&".join([f"{k}={v}" for k, v in params.items()])
 | 
					        params_encode = "&".join([f"{k}={v}" for k, v in params.items()])
 | 
				
			||||||
        url = f"{const.AUTH_API}/services/oauth2/authorize/expid_Login?{params}"
 | 
					        url = f"{const.AUTH_API}/services/oauth2/authorize/expid_Login?{params_encode}"
 | 
				
			||||||
        async with self._request.get(url) as response:
 | 
					        async with self._request.get(url) as response:
 | 
				
			||||||
            text = await response.text()
 | 
					            text = await response.text()
 | 
				
			||||||
            self._expires = datetime.utcnow()
 | 
					            self._expires = datetime.utcnow()
 | 
				
			||||||
@@ -115,7 +117,7 @@ class HonAuth:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async def _manual_redirect(self, url: str) -> str:
 | 
					    async def _manual_redirect(self, url: str) -> str:
 | 
				
			||||||
        async with self._request.get(url, allow_redirects=False) as response:
 | 
					        async with self._request.get(url, allow_redirects=False) as response:
 | 
				
			||||||
            if not (new_location := response.headers.get("Location")):
 | 
					            if not (new_location := response.headers.get("Location", "")):
 | 
				
			||||||
                await self._error_logger(response)
 | 
					                await self._error_logger(response)
 | 
				
			||||||
        return new_location
 | 
					        return new_location
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -138,11 +140,11 @@ class HonAuth:
 | 
				
			|||||||
                )
 | 
					                )
 | 
				
			||||||
                return True
 | 
					                return True
 | 
				
			||||||
            await self._error_logger(response)
 | 
					            await self._error_logger(response)
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _login(self):
 | 
					    async def _login(self) -> str:
 | 
				
			||||||
        start_url = parse.unquote(self._login_data.url.split("startURL=")[-1]).split(
 | 
					        start_url = self._login_data.url.rsplit("startURL=", maxsplit=1)[-1]
 | 
				
			||||||
            "%3D"
 | 
					        start_url = parse.unquote(start_url).split("%3D")[0]
 | 
				
			||||||
        )[0]
 | 
					 | 
				
			||||||
        action = {
 | 
					        action = {
 | 
				
			||||||
            "id": "79;a",
 | 
					            "id": "79;a",
 | 
				
			||||||
            "descriptor": "apex://LightningLoginCustomController/ACTION$login",
 | 
					            "descriptor": "apex://LightningLoginCustomController/ACTION$login",
 | 
				
			||||||
@@ -175,19 +177,13 @@ class HonAuth:
 | 
				
			|||||||
            params=params,
 | 
					            params=params,
 | 
				
			||||||
        ) as response:
 | 
					        ) as response:
 | 
				
			||||||
            if response.status == 200:
 | 
					            if response.status == 200:
 | 
				
			||||||
                try:
 | 
					                with suppress(json.JSONDecodeError, KeyError):
 | 
				
			||||||
                    data = await response.json()
 | 
					                    result = await response.json()
 | 
				
			||||||
                    return data["events"][0]["attributes"]["values"]["url"]
 | 
					                    return result["events"][0]["attributes"]["values"]["url"]
 | 
				
			||||||
                except json.JSONDecodeError:
 | 
					 | 
				
			||||||
                    pass
 | 
					 | 
				
			||||||
                except KeyError:
 | 
					 | 
				
			||||||
                    _LOGGER.error(
 | 
					 | 
				
			||||||
                        "Can't get login url - %s", pformat(await response.json())
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
            await self._error_logger(response)
 | 
					            await self._error_logger(response)
 | 
				
			||||||
            return ""
 | 
					            return ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _parse_token_data(self, text):
 | 
					    def _parse_token_data(self, text: str) -> None:
 | 
				
			||||||
        if access_token := re.findall("access_token=(.*?)&", text):
 | 
					        if access_token := re.findall("access_token=(.*?)&", text):
 | 
				
			||||||
            self._access_token = access_token[0]
 | 
					            self._access_token = access_token[0]
 | 
				
			||||||
        if refresh_token := re.findall("refresh_token=(.*?)&", text):
 | 
					        if refresh_token := re.findall("refresh_token=(.*?)&", text):
 | 
				
			||||||
@@ -195,22 +191,26 @@ class HonAuth:
 | 
				
			|||||||
        if id_token := re.findall("id_token=(.*?)&", text):
 | 
					        if id_token := re.findall("id_token=(.*?)&", text):
 | 
				
			||||||
            self._id_token = id_token[0]
 | 
					            self._id_token = id_token[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _get_token(self, url):
 | 
					    async def _get_token(self, url: str) -> bool:
 | 
				
			||||||
        async with self._request.get(url) as response:
 | 
					        async with self._request.get(url) as response:
 | 
				
			||||||
            if response.status != 200:
 | 
					            if response.status != 200:
 | 
				
			||||||
                await self._error_logger(response)
 | 
					                await self._error_logger(response)
 | 
				
			||||||
                return False
 | 
					                return False
 | 
				
			||||||
            url = re.findall("href\\s*=\\s*[\"'](.+?)[\"']", await response.text())
 | 
					            url_search = re.findall(
 | 
				
			||||||
            if not url:
 | 
					                "href\\s*=\\s*[\"'](.+?)[\"']", await response.text()
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            if not url_search:
 | 
				
			||||||
                await self._error_logger(response)
 | 
					                await self._error_logger(response)
 | 
				
			||||||
                return False
 | 
					                return False
 | 
				
			||||||
        if "ProgressiveLogin" in url[0]:
 | 
					        if "ProgressiveLogin" in url_search[0]:
 | 
				
			||||||
            async with self._request.get(url[0]) as response:
 | 
					            async with self._request.get(url_search[0]) as response:
 | 
				
			||||||
                if response.status != 200:
 | 
					                if response.status != 200:
 | 
				
			||||||
                    await self._error_logger(response)
 | 
					                    await self._error_logger(response)
 | 
				
			||||||
                    return False
 | 
					                    return False
 | 
				
			||||||
                url = re.findall("href\\s*=\\s*[\"'](.*?)[\"']", await response.text())
 | 
					                url_search = re.findall(
 | 
				
			||||||
        url = "/".join(const.AUTH_API.split("/")[:-1]) + url[0]
 | 
					                    "href\\s*=\\s*[\"'](.*?)[\"']", await response.text()
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					        url = "/".join(const.AUTH_API.split("/")[:-1]) + url_search[0]
 | 
				
			||||||
        async with self._request.get(url) as response:
 | 
					        async with self._request.get(url) as response:
 | 
				
			||||||
            if response.status != 200:
 | 
					            if response.status != 200:
 | 
				
			||||||
                await self._error_logger(response)
 | 
					                await self._error_logger(response)
 | 
				
			||||||
@@ -218,7 +218,7 @@ class HonAuth:
 | 
				
			|||||||
            self._parse_token_data(await response.text())
 | 
					            self._parse_token_data(await response.text())
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _api_auth(self):
 | 
					    async def _api_auth(self) -> bool:
 | 
				
			||||||
        post_headers = {"id-token": self._id_token}
 | 
					        post_headers = {"id-token": self._id_token}
 | 
				
			||||||
        data = self._device.get()
 | 
					        data = self._device.get()
 | 
				
			||||||
        async with self._request.post(
 | 
					        async with self._request.post(
 | 
				
			||||||
@@ -232,7 +232,7 @@ class HonAuth:
 | 
				
			|||||||
            self._cognito_token = json_data["cognitoUser"]["Token"]
 | 
					            self._cognito_token = json_data["cognitoUser"]["Token"]
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def authenticate(self):
 | 
					    async def authenticate(self) -> None:
 | 
				
			||||||
        self.clear()
 | 
					        self.clear()
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if not await self._load_login():
 | 
					            if not await self._load_login():
 | 
				
			||||||
@@ -246,7 +246,7 @@ class HonAuth:
 | 
				
			|||||||
        except exceptions.HonNoAuthenticationNeeded:
 | 
					        except exceptions.HonNoAuthenticationNeeded:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def refresh(self):
 | 
					    async def refresh(self) -> bool:
 | 
				
			||||||
        params = {
 | 
					        params = {
 | 
				
			||||||
            "client_id": const.CLIENT_ID,
 | 
					            "client_id": const.CLIENT_ID,
 | 
				
			||||||
            "refresh_token": self._refresh_token,
 | 
					            "refresh_token": self._refresh_token,
 | 
				
			||||||
@@ -264,7 +264,7 @@ class HonAuth:
 | 
				
			|||||||
        self._access_token = data["access_token"]
 | 
					        self._access_token = data["access_token"]
 | 
				
			||||||
        return await self._api_auth()
 | 
					        return await self._api_auth()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def clear(self):
 | 
					    def clear(self) -> None:
 | 
				
			||||||
        self._session.cookie_jar.clear_domain(const.AUTH_API.split("/")[-2])
 | 
					        self._session.cookie_jar.clear_domain(const.AUTH_API.split("/")[-2])
 | 
				
			||||||
        self._request.called_urls = []
 | 
					        self._request.called_urls = []
 | 
				
			||||||
        self._cognito_token = ""
 | 
					        self._cognito_token = ""
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import logging
 | 
					import logging
 | 
				
			||||||
from collections.abc import AsyncIterator
 | 
					from collections.abc import AsyncIterator
 | 
				
			||||||
from contextlib import asynccontextmanager
 | 
					from contextlib import asynccontextmanager
 | 
				
			||||||
from typing import Optional, Callable, Dict
 | 
					from typing import Optional, Callable, Dict, Any
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import aiohttp
 | 
					import aiohttp
 | 
				
			||||||
from typing_extensions import Self
 | 
					from typing_extensions import Self
 | 
				
			||||||
@@ -37,18 +37,18 @@ class ConnectionHandler:
 | 
				
			|||||||
        raise NotImplementedError
 | 
					        raise NotImplementedError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @asynccontextmanager
 | 
					    @asynccontextmanager
 | 
				
			||||||
    async def get(self, *args, **kwargs) -> AsyncIterator[Callable]:
 | 
					    async def get(self, *args, **kwargs) -> AsyncIterator[aiohttp.ClientResponse]:
 | 
				
			||||||
        if self._session is None:
 | 
					        if self._session is None:
 | 
				
			||||||
            raise exceptions.NoSessionException()
 | 
					            raise exceptions.NoSessionException()
 | 
				
			||||||
        response: Callable
 | 
					        response: aiohttp.ClientResponse
 | 
				
			||||||
        async with self._intercept(self._session.get, *args, **kwargs) as response:
 | 
					        async with self._intercept(self._session.get, *args, **kwargs) as response:
 | 
				
			||||||
            yield response
 | 
					            yield response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @asynccontextmanager
 | 
					    @asynccontextmanager
 | 
				
			||||||
    async def post(self, *args, **kwargs) -> AsyncIterator[Callable]:
 | 
					    async def post(self, *args, **kwargs) -> AsyncIterator[aiohttp.ClientResponse]:
 | 
				
			||||||
        if self._session is None:
 | 
					        if self._session is None:
 | 
				
			||||||
            raise exceptions.NoSessionException()
 | 
					            raise exceptions.NoSessionException()
 | 
				
			||||||
        response: Callable
 | 
					        response: aiohttp.ClientResponse
 | 
				
			||||||
        async with self._intercept(self._session.post, *args, **kwargs) as response:
 | 
					        async with self._intercept(self._session.post, *args, **kwargs) as response:
 | 
				
			||||||
            yield response
 | 
					            yield response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ from typing_extensions import Self
 | 
				
			|||||||
from pyhon.connection.auth import HonAuth
 | 
					from pyhon.connection.auth import HonAuth
 | 
				
			||||||
from pyhon.connection.device import HonDevice
 | 
					from pyhon.connection.device import HonDevice
 | 
				
			||||||
from pyhon.connection.handler.base import ConnectionHandler
 | 
					from pyhon.connection.handler.base import ConnectionHandler
 | 
				
			||||||
from pyhon.exceptions import HonAuthenticationError
 | 
					from pyhon.exceptions import HonAuthenticationError, NoAuthenticationException
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,7 +30,9 @@ class HonConnectionHandler(ConnectionHandler):
 | 
				
			|||||||
        self._auth: Optional[HonAuth] = None
 | 
					        self._auth: Optional[HonAuth] = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def auth(self) -> Optional[HonAuth]:
 | 
					    def auth(self) -> HonAuth:
 | 
				
			||||||
 | 
					        if self._auth is None:
 | 
				
			||||||
 | 
					            raise NoAuthenticationException()
 | 
				
			||||||
        return self._auth
 | 
					        return self._auth
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
@@ -39,16 +41,14 @@ class HonConnectionHandler(ConnectionHandler):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    async def create(self) -> Self:
 | 
					    async def create(self) -> Self:
 | 
				
			||||||
        await super().create()
 | 
					        await super().create()
 | 
				
			||||||
        self._auth: HonAuth = HonAuth(
 | 
					        self._auth = HonAuth(self._session, self._email, self._password, self._device)
 | 
				
			||||||
            self._session, self._email, self._password, self._device
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        return self
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _check_headers(self, headers: Dict) -> Dict:
 | 
					    async def _check_headers(self, headers: Dict) -> Dict:
 | 
				
			||||||
        if not (self._auth.cognito_token and self._auth.id_token):
 | 
					        if not (self.auth.cognito_token and self.auth.id_token):
 | 
				
			||||||
            await self._auth.authenticate()
 | 
					            await self.auth.authenticate()
 | 
				
			||||||
        headers["cognito-token"] = self._auth.cognito_token
 | 
					        headers["cognito-token"] = self.auth.cognito_token
 | 
				
			||||||
        headers["id-token"] = self._auth.id_token
 | 
					        headers["id-token"] = self.auth.id_token
 | 
				
			||||||
        return self._HEADERS | headers
 | 
					        return self._HEADERS | headers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @asynccontextmanager
 | 
					    @asynccontextmanager
 | 
				
			||||||
@@ -58,16 +58,16 @@ class HonConnectionHandler(ConnectionHandler):
 | 
				
			|||||||
        kwargs["headers"] = await self._check_headers(kwargs.get("headers", {}))
 | 
					        kwargs["headers"] = await self._check_headers(kwargs.get("headers", {}))
 | 
				
			||||||
        async with method(*args, **kwargs) as response:
 | 
					        async with method(*args, **kwargs) as response:
 | 
				
			||||||
            if (
 | 
					            if (
 | 
				
			||||||
                self._auth.token_expires_soon or response.status in [401, 403]
 | 
					                self.auth.token_expires_soon or response.status in [401, 403]
 | 
				
			||||||
            ) and loop == 0:
 | 
					            ) and loop == 0:
 | 
				
			||||||
                _LOGGER.info("Try refreshing token...")
 | 
					                _LOGGER.info("Try refreshing token...")
 | 
				
			||||||
                await self._auth.refresh()
 | 
					                await self.auth.refresh()
 | 
				
			||||||
                async with self._intercept(
 | 
					                async with self._intercept(
 | 
				
			||||||
                    method, *args, loop=loop + 1, **kwargs
 | 
					                    method, *args, loop=loop + 1, **kwargs
 | 
				
			||||||
                ) as result:
 | 
					                ) as result:
 | 
				
			||||||
                    yield result
 | 
					                    yield result
 | 
				
			||||||
            elif (
 | 
					            elif (
 | 
				
			||||||
                self._auth.token_is_expired or response.status in [401, 403]
 | 
					                self.auth.token_is_expired or response.status in [401, 403]
 | 
				
			||||||
            ) and loop == 1:
 | 
					            ) and loop == 1:
 | 
				
			||||||
                _LOGGER.warning(
 | 
					                _LOGGER.warning(
 | 
				
			||||||
                    "%s - Error %s - %s",
 | 
					                    "%s - Error %s - %s",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
import asyncio
 | 
					import asyncio
 | 
				
			||||||
from typing import List, Optional, Dict
 | 
					from typing import List, Optional, Dict, Any
 | 
				
			||||||
from typing_extensions import Self
 | 
					from typing_extensions import Self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from aiohttp import ClientSession
 | 
					from aiohttp import ClientSession
 | 
				
			||||||
@@ -39,8 +39,8 @@ class Hon:
 | 
				
			|||||||
    def appliances(self) -> List[HonAppliance]:
 | 
					    def appliances(self) -> List[HonAppliance]:
 | 
				
			||||||
        return self._appliances
 | 
					        return self._appliances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _create_appliance(self, appliance: Dict, zone=0) -> None:
 | 
					    async def _create_appliance(self, appliance_data: Dict[str, Any], zone=0) -> None:
 | 
				
			||||||
        appliance = HonAppliance(self._api, appliance, zone=zone)
 | 
					        appliance = HonAppliance(self._api, appliance_data, zone=zone)
 | 
				
			||||||
        if appliance.mac_address is None:
 | 
					        if appliance.mac_address is None:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        await asyncio.gather(
 | 
					        await asyncio.gather(
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user