Skip to content

Commit 4325952

Browse files
authored
Merge pull request #196 from dvd-dev/blocking_call3
Amélioration pour éviter les blocking calls au disque
2 parents d41d9f6 + b3c365f commit 4325952

File tree

6 files changed

+30
-23
lines changed

6 files changed

+30
-23
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ repos:
4949
files: ^pyhilo/.+\.py$
5050
additional_dependencies:
5151
- types-python-dateutil==2.8.0
52+
- types-aiofiles==23.2.0
5253

5354
- repo: https://github.com/pre-commit/pre-commit-hooks
5455
rev: v2.4.0

pyhilo/api.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
from pyhilo.device import DeviceAttribute, HiloDevice, get_device_attributes
4646
from pyhilo.exceptions import InvalidCredentialsError, RequestError
4747
from pyhilo.util.state import (
48+
StateDict,
4849
WebsocketDict,
4950
WebsocketTransportsDict,
5051
get_state,
@@ -75,7 +76,7 @@ def __init__(
7576
self._backoff_refresh_lock_ws = asyncio.Lock()
7677
self._request_retries = request_retries
7778
self._state_yaml: str = DEFAULT_STATE_FILE
78-
self.state = get_state(self._state_yaml)
79+
self.state: StateDict = {}
7980
self.async_request = self._wrap_request_method(self._request_retries)
8081
self.device_attributes = get_device_attributes()
8182
self.session: ClientSession = session
@@ -152,14 +153,14 @@ def dev_atts(
152153
else attribute,
153154
)
154155

155-
def _get_fid_state(self) -> bool:
156+
async def _get_fid_state(self) -> bool:
156157
"""Looks up the cached state to define the firebase attributes
157158
on the API instances.
158159
159160
:return: Whether or not we have cached firebase state
160161
:rtype: bool
161162
"""
162-
self.state = get_state(self._state_yaml)
163+
self.state = await get_state(self._state_yaml)
163164
fb_state = self.state.get("firebase", {})
164165
if fb_fid := fb_state.get("fid"):
165166
self._fb_fid = fb_fid
@@ -171,14 +172,14 @@ def _get_fid_state(self) -> bool:
171172
return True
172173
return False
173174

174-
def _get_android_state(self) -> bool:
175+
async def _get_android_state(self) -> bool:
175176
"""Looks up the cached state to define the android device token
176177
on the API instances.
177178
178179
:return: Whether or not we have cached android state
179180
:rtype: bool
180181
"""
181-
self.state = get_state(self._state_yaml)
182+
self.state = await get_state(self._state_yaml)
182183
android_state = self.state.get("android", {})
183184
if token := android_state.get("token"):
184185
self._device_token = token
@@ -187,18 +188,18 @@ def _get_android_state(self) -> bool:
187188

188189
async def _get_device_token(self) -> None:
189190
"""Retrieves the android token if it's not cached."""
190-
if not self._get_android_state():
191+
if not await self._get_android_state():
191192
await self.android_register()
192193

193194
async def _get_fid(self) -> None:
194195
"""Retrieves the firebase state if it's not cached."""
195-
if not self._get_fid_state():
196+
if not await self._get_fid_state():
196197
self._fb_id = "".join(
197198
random.SystemRandom().choice(string.ascii_letters + string.digits)
198199
for _ in range(FB_ID_LEN)
199200
)
200201
await self.fb_install(self._fb_id)
201-
self._get_fid_state()
202+
await self._get_fid_state()
202203

203204
async def _async_request(
204205
self, method: str, endpoint: str, host: str = API_HOSTNAME, **kwargs: Any
@@ -366,7 +367,7 @@ async def post_devicehub_negociate(self) -> tuple[str, str]:
366367
resp = await self.async_request("post", url)
367368
ws_url = resp.get("url")
368369
ws_token = resp.get("accessToken")
369-
set_state(
370+
await set_state(
370371
self._state_yaml,
371372
"websocket",
372373
{
@@ -397,7 +398,7 @@ async def get_websocket_params(self) -> None:
397398
"available_transports": transport_dict,
398399
"full_ws_url": self.full_ws_url,
399400
}
400-
set_state(self._state_yaml, "websocket", websocket_dict)
401+
await set_state(self._state_yaml, "websocket", websocket_dict)
401402

402403
async def fb_install(self, fb_id: str) -> None:
403404
LOG.debug("Posting firebase install")
@@ -422,7 +423,7 @@ async def fb_install(self, fb_id: str) -> None:
422423
raise RequestError(err) from err
423424
LOG.debug(f"FB Install data: {resp}")
424425
auth_token = resp.get("authToken", {})
425-
set_state(
426+
await set_state(
426427
self._state_yaml,
427428
"firebase",
428429
{
@@ -463,7 +464,7 @@ async def android_register(self) -> None:
463464
LOG.error(f"Android registration error: {msg}")
464465
raise RequestError
465466
token = msg.split("=")[-1]
466-
set_state(
467+
await set_state(
467468
self._state_yaml,
468469
"android",
469470
{

pyhilo/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
LOG: Final = logging.getLogger(__package__)
99
DEFAULT_STATE_FILE: Final = "hilo_state.yaml"
1010
REQUEST_RETRY: Final = 9
11-
PYHILO_VERSION: Final = "2024.04.01"
11+
PYHILO_VERSION: Final = "2024.06.01"
1212
# TODO: Find a way to keep previous line in sync with pyproject.toml automatically
1313

1414
CONTENT_TYPE_FORM: Final = "application/x-www-form-urlencoded"

pyhilo/util/state.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from os.path import isfile
33
from typing import Any, Optional, Type, TypedDict, TypeVar, Union
44

5+
import aiofiles
56
import ruyaml as yaml
67

78
from pyhilo.const import LOG
@@ -71,21 +72,22 @@ def __get_defaults__(cls: Type[T]) -> dict[str, Any]:
7172
return new_dict # type: ignore
7273

7374

74-
def get_state(state_yaml: str) -> StateDict:
75+
async def get_state(state_yaml: str) -> StateDict:
7576
"""Read in state yaml.
7677
:param state_yaml: filename where to read the state
7778
:type state_yaml: ``str``
7879
:rtype: ``StateDict``
7980
"""
8081
if not isfile(state_yaml):
8182
return __get_defaults__(StateDict) # type: ignore
82-
with open(state_yaml) as yaml_file:
83+
async with aiofiles.open(state_yaml, mode="r") as yaml_file:
8384
LOG.debug("Loading state from yaml")
84-
state_yaml_payload: StateDict = yaml.load(yaml_file, Loader=yaml.Loader)
85+
content = await yaml_file.read()
86+
state_yaml_payload: StateDict = yaml.safe_load(content)
8587
return state_yaml_payload
8688

8789

88-
def set_state(
90+
async def set_state(
8991
state_yaml: str,
9092
key: str,
9193
state: Union[
@@ -101,9 +103,10 @@ def set_state(
101103
:type state: ``StateDict``
102104
:rtype: ``StateDict``
103105
"""
104-
current_state = get_state(state_yaml) or {}
106+
current_state = await get_state(state_yaml) or {}
105107
merged_state: dict[str, Any] = {key: {**current_state.get(key, {}), **state}} # type: ignore
106108
new_state: dict[str, Any] = {**current_state, **merged_state}
107-
with open(state_yaml, "w") as yaml_file:
109+
async with aiofiles.open(state_yaml, mode="w") as yaml_file:
108110
LOG.debug("Saving state to yaml file")
109-
yaml.dump(new_state, yaml_file, Dumper=yaml.RoundTripDumper)
111+
content = yaml.dump(new_state)
112+
await yaml_file.write(content)

pyproject.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ disallow_untyped_defs = true
2727
follow_imports = "silent"
2828
ignore_missing_imports = true
2929
no_implicit_optional = true
30-
python_version = "3.9"
30+
python_version = "3.11"
3131
show_error_codes = true
3232
strict_equality = true
3333
warn_incomplete_stub = true
@@ -40,7 +40,7 @@ exclude = ".venv/.*"
4040

4141
[tool.poetry]
4242
name = "python-hilo"
43-
version = "2024.4.1"
43+
version = "2024.6.1"
4444
description = "A Python3, async interface to the Hilo API"
4545
readme = "README.md"
4646
authors = ["David Vallee Delisle <me@dvd.dev>"]
@@ -65,6 +65,7 @@ classifiers = [
6565

6666
[tool.poetry.dependencies]
6767
aiohttp = ">=3.8.0"
68+
aiofiles = ">=23.2.1"
6869
aiosignal = ">=1.2.0"
6970
async-timeout = ">=4.0.0"
7071
attrs = ">=21.2.0"
@@ -73,7 +74,7 @@ python-dateutil = ">=2.8.2"
7374
ruyaml = ">=0.91.0"
7475
python = "^3.9.0"
7576
voluptuous = ">=0.13.1"
76-
websockets = ">=8.1,<12.0"
77+
websockets = ">=8.1,<13.0"
7778

7879
[tool.poetry.dev-dependencies]
7980
Sphinx = "^7.1.2"

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
aiofiles >=23.2.1
12
aiohttp>=3.8.0
23
aiosignal>=1.1.0
34
async-timeout>=4.0.0

0 commit comments

Comments
 (0)