Skip to content

Commit 0089da8

Browse files
authored
Set appropriate timeouts for clients without option (#23)
1 parent dd6486f commit 0089da8

File tree

12 files changed

+51
-26
lines changed

12 files changed

+51
-26
lines changed

aiohasupervisor/addons.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Any
44

55
from .client import _SupervisorComponentClient
6-
from .const import ResponseType
6+
from .const import TIMEOUT_60_SECONDS, ResponseType
77
from .models.addons import (
88
AddonsConfigValidate,
99
AddonsList,
@@ -38,19 +38,20 @@ async def uninstall_addon(
3838
await self._client.post(
3939
f"addons/{addon}/uninstall",
4040
json=options.to_dict() if options else None,
41+
timeout=TIMEOUT_60_SECONDS,
4142
)
4243

4344
async def start_addon(self, addon: str) -> None:
4445
"""Start an addon."""
45-
await self._client.post(f"addons/{addon}/start")
46+
await self._client.post(f"addons/{addon}/start", timeout=TIMEOUT_60_SECONDS)
4647

4748
async def stop_addon(self, addon: str) -> None:
4849
"""Stop an addon."""
49-
await self._client.post(f"addons/{addon}/stop")
50+
await self._client.post(f"addons/{addon}/stop", timeout=TIMEOUT_60_SECONDS)
5051

5152
async def restart_addon(self, addon: str) -> None:
5253
"""Restart an addon."""
53-
await self._client.post(f"addons/{addon}/restart")
54+
await self._client.post(f"addons/{addon}/restart", timeout=None)
5455

5556
async def addon_options(self, addon: str, options: AddonsOptions) -> None:
5657
"""Set options for addon."""

aiohasupervisor/backups.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ async def full_backup(self, options: FullBackupOptions | None = None) -> NewBack
5555
"backups/new/full",
5656
json=options.to_dict() if options else None,
5757
response_type=ResponseType.JSON,
58+
timeout=None,
5859
)
5960
return NewBackup.from_dict(result.data)
6061

@@ -64,6 +65,7 @@ async def partial_backup(self, options: PartialBackupOptions) -> NewBackup:
6465
"backups/new/partial",
6566
json=options.to_dict(),
6667
response_type=ResponseType.JSON,
68+
timeout=None,
6769
)
6870
return NewBackup.from_dict(result.data)
6971

@@ -84,6 +86,7 @@ async def full_restore(
8486
f"backups/{backup}/restore/full",
8587
json=options.to_dict() if options else None,
8688
response_type=ResponseType.JSON,
89+
timeout=None,
8790
)
8891
return BackupJob.from_dict(result.data)
8992

@@ -95,6 +98,7 @@ async def partial_restore(
9598
f"backups/{backup}/restore/partial",
9699
json=options.to_dict(),
97100
response_type=ResponseType.JSON,
101+
timeout=None,
98102
)
99103
return BackupJob.from_dict(result.data)
100104

aiohasupervisor/client.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
)
1515
from yarl import URL
1616

17-
from .const import ResponseType
17+
from .const import DEFAULT_TIMEOUT, ResponseType
1818
from .exceptions import (
1919
SupervisorAuthenticationError,
2020
SupervisorBadRequestError,
@@ -50,15 +50,9 @@ class _SupervisorClient:
5050

5151
api_host: str
5252
token: str
53-
request_timeout: int
5453
session: ClientSession | None = None
5554
_close_session: bool = field(default=False, init=False)
5655

57-
@property
58-
def timeout(self) -> ClientTimeout:
59-
"""Timeout for requests."""
60-
return ClientTimeout(total=self.request_timeout)
61-
6256
async def _request(
6357
self,
6458
method: HTTPMethod,
@@ -68,6 +62,7 @@ async def _request(
6862
response_type: ResponseType,
6963
json: dict[str, Any] | None = None,
7064
data: Any = None,
65+
timeout: ClientTimeout | None = DEFAULT_TIMEOUT,
7166
) -> Response:
7267
"""Handle a request to Supervisor."""
7368
try:
@@ -102,7 +97,7 @@ async def _request(
10297
async with self.session.request(
10398
method.value,
10499
url,
105-
timeout=self.timeout,
100+
timeout=timeout,
106101
headers=headers,
107102
params=params,
108103
json=json,
@@ -153,13 +148,15 @@ async def get(
153148
*,
154149
params: dict[str, str] | None = None,
155150
response_type: ResponseType = ResponseType.JSON,
151+
timeout: ClientTimeout | None = DEFAULT_TIMEOUT,
156152
) -> Response:
157153
"""Handle a GET request to Supervisor."""
158154
return await self._request(
159155
HTTPMethod.GET,
160156
uri,
161157
params=params,
162158
response_type=response_type,
159+
timeout=timeout,
163160
)
164161

165162
async def post(
@@ -170,6 +167,7 @@ async def post(
170167
response_type: ResponseType = ResponseType.NONE,
171168
json: dict[str, Any] | None = None,
172169
data: Any = None,
170+
timeout: ClientTimeout | None = DEFAULT_TIMEOUT,
173171
) -> Response:
174172
"""Handle a POST request to Supervisor."""
175173
return await self._request(
@@ -179,6 +177,7 @@ async def post(
179177
response_type=response_type,
180178
json=json,
181179
data=data,
180+
timeout=timeout,
182181
)
183182

184183
async def put(
@@ -187,6 +186,7 @@ async def put(
187186
*,
188187
params: dict[str, str] | None = None,
189188
json: dict[str, Any] | None = None,
189+
timeout: ClientTimeout | None = DEFAULT_TIMEOUT,
190190
) -> Response:
191191
"""Handle a PUT request to Supervisor."""
192192
return await self._request(
@@ -195,20 +195,23 @@ async def put(
195195
params=params,
196196
response_type=ResponseType.NONE,
197197
json=json,
198+
timeout=timeout,
198199
)
199200

200201
async def delete(
201202
self,
202203
uri: str,
203204
*,
204205
params: dict[str, str] | None = None,
206+
timeout: ClientTimeout | None = DEFAULT_TIMEOUT,
205207
) -> Response:
206208
"""Handle a DELETE request to Supervisor."""
207209
return await self._request(
208210
HTTPMethod.DELETE,
209211
uri,
210212
params=params,
211213
response_type=ResponseType.NONE,
214+
timeout=timeout,
212215
)
213216

214217
async def close(self) -> None:

aiohasupervisor/const.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
from enum import StrEnum
44

5+
from aiohttp import ClientTimeout
6+
7+
DEFAULT_TIMEOUT = ClientTimeout(total=10)
8+
TIMEOUT_60_SECONDS = ClientTimeout(total=60)
9+
510

611
class ResponseType(StrEnum):
712
"""Expected response type."""

aiohasupervisor/discovery.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from uuid import UUID
44

55
from .client import _SupervisorComponentClient
6-
from .const import ResponseType
6+
from .const import TIMEOUT_60_SECONDS, ResponseType
77
from .models.discovery import Discovery, DiscoveryConfig, DiscoveryList, SetDiscovery
88

99

@@ -12,7 +12,7 @@ class DiscoveryClient(_SupervisorComponentClient):
1212

1313
async def list(self) -> list[Discovery]:
1414
"""List discovered active services."""
15-
result = await self._client.get("discovery")
15+
result = await self._client.get("discovery", timeout=TIMEOUT_60_SECONDS)
1616
return DiscoveryList.from_dict(result.data).discovery
1717

1818
async def get(self, uuid: UUID) -> Discovery:

aiohasupervisor/homeassistant.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ async def options(self, options: HomeAssistantOptions) -> None:
3232
async def update(self, options: HomeAssistantUpdateOptions | None = None) -> None:
3333
"""Update Home Assistant."""
3434
await self._client.post(
35-
"core/update", json=options.to_dict() if options else None
35+
"core/update", json=options.to_dict() if options else None, timeout=None
3636
)
3737

3838
async def restart(self, options: HomeAssistantRestartOptions | None = None) -> None:

aiohasupervisor/host.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Host client for supervisor."""
22

33
from .client import _SupervisorComponentClient
4+
from .const import TIMEOUT_60_SECONDS
45
from .models.host import (
56
HostInfo,
67
HostOptions,
@@ -22,7 +23,9 @@ async def info(self) -> HostInfo:
2223
async def reboot(self, options: RebootOptions | None = None) -> None:
2324
"""Reboot host."""
2425
await self._client.post(
25-
"host/reboot", json=options.to_dict() if options else None
26+
"host/reboot",
27+
json=options.to_dict() if options else None,
28+
timeout=TIMEOUT_60_SECONDS,
2629
)
2730

2831
async def shutdown(self, options: ShutdownOptions | None = None) -> None:

aiohasupervisor/os.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ async def info(self) -> OSInfo:
2626
async def update(self, options: OSUpdate | None = None) -> None:
2727
"""Update OS."""
2828
await self._client.post(
29-
"os/update", json=options.to_dict() if options else None
29+
"os/update", json=options.to_dict() if options else None, timeout=None
3030
)
3131

3232
async def config_sync(self) -> None:

aiohasupervisor/resolution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ async def run_check(self, check: CheckType | str) -> None:
3434

3535
async def apply_suggestion(self, suggestion: UUID) -> None:
3636
"""Apply a suggestion."""
37-
await self._client.post(f"resolution/suggestion/{suggestion.hex}")
37+
await self._client.post(f"resolution/suggestion/{suggestion.hex}", timeout=None)
3838

3939
async def dismiss_suggestion(self, suggestion: UUID) -> None:
4040
"""Dismiss a suggestion."""

aiohasupervisor/root.py

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

33
from typing import Self
44

5-
from aiohttp import ClientSession
5+
from aiohttp import ClientSession, ClientTimeout
66

77
from .addons import AddonsClient
88
from .backups import BackupsClient
@@ -25,11 +25,10 @@ def __init__(
2525
self,
2626
api_host: str,
2727
token: str,
28-
request_timeout: int = 10,
2928
session: ClientSession | None = None,
3029
) -> None:
3130
"""Initialize client."""
32-
self._client = _SupervisorClient(api_host, token, request_timeout, session)
31+
self._client = _SupervisorClient(api_host, token, session)
3332
self._addons = AddonsClient(self._client)
3433
self._os = OSClient(self._client)
3534
self._backups = BackupsClient(self._client)
@@ -98,7 +97,7 @@ async def info(self) -> RootInfo:
9897

9998
async def refresh_updates(self) -> None:
10099
"""Refresh updates."""
101-
await self._client.post("refresh_updates")
100+
await self._client.post("refresh_updates", timeout=ClientTimeout(total=300))
102101

103102
async def available_updates(self) -> list[AvailableUpdate]:
104103
"""Get available updates."""

0 commit comments

Comments
 (0)