Skip to content

Commit 0176c9a

Browse files
committed
Refactor type hints in OverkizClient and models for improved clarity and consistency
1 parent 279892c commit 0176c9a

3 files changed

Lines changed: 31 additions & 32 deletions

File tree

pyoverkiz/client.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
from pyoverkiz.obfuscate import obfuscate_sensitive_data
6060
from pyoverkiz.response_handler import check_response
6161
from pyoverkiz.serializers import prepare_payload
62-
from pyoverkiz.types import JSON
6362

6463
_LOGGER = logging.getLogger(__name__)
6564

@@ -404,7 +403,7 @@ async def get_execution_history(self) -> list[HistoryExecution]:
404403
return converter.structure(decamelize(response), list[HistoryExecution])
405404

406405
@retry_on_auth_error
407-
async def get_device_definition(self, deviceurl: str) -> JSON | None:
406+
async def get_device_definition(self, deviceurl: str) -> dict[str, Any] | None:
408407
"""Retrieve a particular setup device definition."""
409408
response: dict = await self._get(
410409
f"setup/devices/{urllib.parse.quote_plus(deviceurl)}"
@@ -696,19 +695,23 @@ async def get_setup_option_parameter(
696695
return None
697696

698697
@retry_on_auth_error
699-
async def get_reference_controllable(self, controllable_name: str) -> JSON:
698+
async def get_reference_controllable(
699+
self, controllable_name: str
700+
) -> dict[str, Any]:
700701
"""Get a controllable definition."""
701702
return await self._get(
702703
f"reference/controllable/{urllib.parse.quote_plus(controllable_name)}"
703704
)
704705

705706
@retry_on_auth_error
706-
async def get_reference_controllable_types(self) -> JSON:
707+
async def get_reference_controllable_types(self) -> list[dict[str, Any]]:
707708
"""Get details about all supported controllable types."""
708709
return await self._get("reference/controllableTypes")
709710

710711
@retry_on_auth_error
711-
async def search_reference_devices_model(self, payload: JSON) -> JSON:
712+
async def search_reference_devices_model(
713+
self, payload: dict[str, Any]
714+
) -> dict[str, Any]:
712715
"""Search reference device models using a POST payload."""
713716
return await self._post("reference/devices/search", payload)
714717

@@ -727,7 +730,7 @@ async def get_reference_protocol_types(self) -> list[ProtocolType]:
727730
return converter.structure(response, list[ProtocolType])
728731

729732
@retry_on_auth_error
730-
async def get_reference_timezones(self) -> JSON:
733+
async def get_reference_timezones(self) -> list[dict[str, Any]]:
731734
"""Get timezones list."""
732735
return await self._get("reference/timezones")
733736

@@ -824,7 +827,10 @@ async def _get(self, path: str) -> Any:
824827
return await self._parse_response(response)
825828

826829
async def _post(
827-
self, path: str, payload: JSON | None = None, data: JSON | None = None
830+
self,
831+
path: str,
832+
payload: dict[str, Any] | None = None,
833+
data: dict[str, Any] | None = None,
828834
) -> Any:
829835
"""Make a POST request to the OverKiz API."""
830836
await self._refresh_token_if_expired()
@@ -838,7 +844,7 @@ async def _post(
838844
) as response:
839845
return await self._parse_response(response)
840846

841-
async def _put(self, path: str, payload: JSON | None = None) -> Any:
847+
async def _put(self, path: str, payload: dict[str, Any] | None = None) -> Any:
842848
"""Make a PUT request to the OverKiz API."""
843849
await self._refresh_token_if_expired()
844850

pyoverkiz/models.py

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import json
66
import re
7-
from collections.abc import Iterator
7+
from collections.abc import Iterator, Mapping
88
from typing import Any, cast
99

1010
from attr import define, field
@@ -24,11 +24,11 @@
2424
UpdateBoxStatus,
2525
UpdateCriticityLevel,
2626
)
27-
from pyoverkiz.enums.command import OverkizCommand, OverkizCommandParam
27+
from pyoverkiz.enums.command import OverkizCommand
2828
from pyoverkiz.enums.protocol import Protocol
2929
from pyoverkiz.enums.server import APIType, Server
3030
from pyoverkiz.obfuscate import obfuscate_email, obfuscate_id, obfuscate_string
31-
from pyoverkiz.types import DATA_TYPE_TO_PYTHON, StateType
31+
from pyoverkiz.types import DATA_TYPE_TO_PYTHON, CommandParameterValue, StateType
3232

3333
# ---------------------------------------------------------------------------
3434
# State & command primitives
@@ -129,8 +129,8 @@ def _cast_json_value(self, raw_value: str) -> StateType:
129129

130130

131131
@define(init=False)
132-
class States:
133-
"""Container of State objects providing lookup and mapping helpers."""
132+
class States(Mapping[str, State]):
133+
"""Container of State objects implementing Mapping[str, State]."""
134134

135135
_states: list[State]
136136
_index: dict[str, State]
@@ -142,9 +142,9 @@ def __init__(self, states: list[State] | None = None) -> None:
142142
self._index = {state.name: state for state in self._states}
143143
self._pos = {state.name: i for i, state in enumerate(self._states)}
144144

145-
def __iter__(self) -> Iterator[State]:
146-
"""Return an iterator over contained State objects."""
147-
return self._states.__iter__()
145+
def __iter__(self) -> Iterator[str]:
146+
"""Return an iterator over state names."""
147+
return iter(self._index)
148148

149149
def __contains__(self, name: object) -> bool:
150150
"""Return True if a state with the given name exists in the container."""
@@ -172,10 +172,6 @@ def __len__(self) -> int:
172172
"""Return number of states in the container."""
173173
return len(self._states)
174174

175-
def get(self, name: str) -> State | None:
176-
"""Return the State with the given name or None if missing."""
177-
return self._index.get(name)
178-
179175
def select(self, names: list[str]) -> State | None:
180176
"""Return the first State that exists and has a non-None value, or None."""
181177
for name in names:
@@ -204,8 +200,8 @@ class CommandDefinition:
204200

205201

206202
@define(init=False)
207-
class CommandDefinitions:
208-
"""Container for command definitions providing convenient lookup by name."""
203+
class CommandDefinitions(Mapping[str, CommandDefinition]):
204+
"""Container for command definitions implementing Mapping[str, CommandDefinition]."""
209205

210206
_commands: list[CommandDefinition]
211207
_index: dict[str, CommandDefinition]
@@ -215,9 +211,9 @@ def __init__(self, commands: list[CommandDefinition] | None = None) -> None:
215211
self._commands = list(commands) if commands else []
216212
self._index = {cd.command_name: cd for cd in self._commands}
217213

218-
def __iter__(self) -> Iterator[CommandDefinition]:
219-
"""Iterate over defined commands."""
220-
return self._commands.__iter__()
214+
def __iter__(self) -> Iterator[str]:
215+
"""Iterate over command names."""
216+
return iter(self._index)
221217

222218
def __contains__(self, name: object) -> bool:
223219
"""Return True if a command with `name` exists."""
@@ -234,10 +230,6 @@ def __len__(self) -> int:
234230
"""Return number of command definitions."""
235231
return len(self._commands)
236232

237-
def get(self, command: str) -> CommandDefinition | None:
238-
"""Return the command definition or None if missing."""
239-
return self._index.get(command)
240-
241233
def select(self, commands: list[str | OverkizCommand]) -> str | None:
242234
"""Return the first command name that exists in this definition, or None."""
243235
return next(
@@ -283,7 +275,7 @@ class Command:
283275
"""Represents an OverKiz Command."""
284276

285277
name: str | OverkizCommand
286-
parameters: list[str | int | float | OverkizCommandParam] | None = None
278+
parameters: list[CommandParameterValue] | None = None
287279
type: int | None = None
288280

289281
def to_payload(self) -> dict[str, object]:

pyoverkiz/types.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77
from typing import Any
88

99
from pyoverkiz.enums import DataType
10+
from pyoverkiz.enums.command import OverkizCommandParam
1011

1112
StateType = str | int | float | bool | dict[str, Any] | list[Any] | None
1213

14+
CommandParameterValue = str | int | float | bool | OverkizCommandParam
15+
1316

1417
def _parse_bool(value: str) -> bool:
1518
"""Parse a string value into a boolean.
@@ -27,5 +30,3 @@ def _parse_bool(value: str) -> bool:
2730
DataType.JSON_ARRAY: json.loads,
2831
DataType.JSON_OBJECT: json.loads,
2932
}
30-
31-
JSON = dict[str, Any] | list[dict[str, Any]] # pylint: disable=invalid-name

0 commit comments

Comments
 (0)