Skip to content

Commit ddc2da5

Browse files
committed
refactor: deduplicate actions methods and improve typing
1 parent c314c8a commit ddc2da5

File tree

14 files changed

+615
-699
lines changed

14 files changed

+615
-699
lines changed

hcloud/actions/__init__.py

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

33
from .client import (
44
ActionsClient,
5+
ActionSort,
56
ActionsPageResult,
67
BoundAction,
78
ResourceActionsClient,
@@ -10,15 +11,18 @@
1011
Action,
1112
ActionException,
1213
ActionFailedException,
14+
ActionStatus,
1315
ActionTimeoutException,
1416
)
1517

1618
__all__ = [
1719
"Action",
20+
"ActionStatus",
1821
"ActionException",
1922
"ActionFailedException",
2023
"ActionTimeoutException",
2124
"ActionsClient",
25+
"ActionSort",
2226
"ActionsPageResult",
2327
"BoundAction",
2428
"ResourceActionsClient",

hcloud/actions/client.py

Lines changed: 97 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import time
44
import warnings
5-
from typing import TYPE_CHECKING, Any, NamedTuple
5+
from typing import TYPE_CHECKING, Any, Literal, NamedTuple
66

77
from ..core import BoundModelBase, Meta, ResourceClientBase
8-
from .domain import Action, ActionFailedException, ActionTimeoutException
8+
from .domain import Action, ActionFailedException, ActionStatus, ActionTimeoutException
99

1010
if TYPE_CHECKING:
1111
from .._client import Client
@@ -45,12 +45,78 @@ def wait_until_finished(self, max_retries: int | None = None) -> None:
4545
raise ActionFailedException(action=self)
4646

4747

48+
ActionSort = Literal[
49+
"id",
50+
"id:asc",
51+
"id:desc",
52+
"command",
53+
"command:asc",
54+
"command:desc",
55+
"status",
56+
"status:asc",
57+
"status:desc",
58+
"started",
59+
"started:asc",
60+
"started:desc",
61+
"finished",
62+
"finished:asc",
63+
"finished:desc",
64+
]
65+
66+
4867
class ActionsPageResult(NamedTuple):
4968
actions: list[BoundAction]
5069
meta: Meta
5170

5271

53-
class ResourceActionsClient(ResourceClientBase):
72+
class ResourceClientBaseActionsMixin(ResourceClientBase):
73+
def _get_action_by_id(
74+
self,
75+
base_url: str,
76+
id: int,
77+
) -> BoundAction:
78+
response = self._client.request(
79+
method="GET",
80+
url=f"{base_url}/actions/{id}",
81+
)
82+
return BoundAction(
83+
client=self._parent.actions,
84+
data=response["action"],
85+
)
86+
87+
def _get_actions_list(
88+
self,
89+
base_url: str,
90+
status: list[ActionStatus] | None = None,
91+
sort: list[ActionSort] | None = None,
92+
page: int | None = None,
93+
per_page: int | None = None,
94+
) -> ActionsPageResult:
95+
params: dict[str, Any] = {}
96+
if status is not None:
97+
params["status"] = status
98+
if sort is not None:
99+
params["sort"] = sort
100+
if page is not None:
101+
params["page"] = page
102+
if per_page is not None:
103+
params["per_page"] = per_page
104+
105+
response = self._client.request(
106+
method="GET",
107+
url=f"{base_url}/actions",
108+
params=params,
109+
)
110+
return ActionsPageResult(
111+
actions=[BoundAction(self._parent.actions, o) for o in response["actions"]],
112+
meta=Meta.parse_meta(response),
113+
)
114+
115+
116+
class ResourceActionsClient(
117+
ResourceClientBaseActionsMixin,
118+
ResourceClientBase,
119+
):
54120
_resource: str
55121

56122
def __init__(self, client: ResourceClientBase | Client, resource: str | None):
@@ -66,69 +132,46 @@ def __init__(self, client: ResourceClientBase | Client, resource: str | None):
66132
self._resource = resource or ""
67133

68134
def get_by_id(self, id: int) -> BoundAction:
69-
"""Get a specific action by its ID.
135+
"""
136+
Returns a specific Action by its ID.
70137
71-
:param id: int
72-
:return: :class:`BoundAction <hcloud.actions.client.BoundAction>`
138+
:param id: ID of the Action.
73139
"""
74-
response = self._client.request(
75-
url=f"{self._resource}/actions/{id}",
76-
method="GET",
77-
)
78-
return BoundAction(self._parent.actions, response["action"])
140+
return self._get_action_by_id(self._resource, id)
79141

80142
def get_list(
81143
self,
82-
status: list[str] | None = None,
83-
sort: list[str] | None = None,
144+
status: list[ActionStatus] | None = None,
145+
sort: list[ActionSort] | None = None,
84146
page: int | None = None,
85147
per_page: int | None = None,
86148
) -> ActionsPageResult:
87-
"""Get a list of actions.
88-
89-
:param status: List[str] (optional)
90-
Response will have only actions with specified statuses. Choices: `running` `success` `error`
91-
:param sort: List[str] (optional)
92-
Specify how the results are sorted. Choices: `id` `command` `status` `progress` `started` `finished` . You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default)
93-
:param page: int (optional)
94-
Specifies the page to fetch
95-
:param per_page: int (optional)
96-
Specifies how many results are returned by page
97-
:return: (List[:class:`BoundAction <hcloud.actions.client.BoundAction>`], :class:`Meta <hcloud.core.domain.Meta>`)
98149
"""
99-
params: dict[str, Any] = {}
100-
if status is not None:
101-
params["status"] = status
102-
if sort is not None:
103-
params["sort"] = sort
104-
if page is not None:
105-
params["page"] = page
106-
if per_page is not None:
107-
params["per_page"] = per_page
150+
Returns a paginated list of Actions.
108151
109-
response = self._client.request(
110-
url=f"{self._resource}/actions",
111-
method="GET",
112-
params=params,
152+
:param status: Filter the Actions by status.
153+
:param sort: Sort Actions by field and direction.
154+
:param page: Page number to get.
155+
:param per_page: Maximum number of Actions returned per page.
156+
"""
157+
return self._get_actions_list(
158+
self._resource,
159+
status=status,
160+
sort=sort,
161+
page=page,
162+
per_page=per_page,
113163
)
114-
actions = [
115-
BoundAction(self._parent.actions, action_data)
116-
for action_data in response["actions"]
117-
]
118-
return ActionsPageResult(actions, Meta.parse_meta(response))
119164

120165
def get_all(
121166
self,
122-
status: list[str] | None = None,
123-
sort: list[str] | None = None,
167+
status: list[ActionStatus] | None = None,
168+
sort: list[ActionSort] | None = None,
124169
) -> list[BoundAction]:
125-
"""Get all actions.
170+
"""
171+
Returns all Actions.
126172
127-
:param status: List[str] (optional)
128-
Response will have only actions with specified statuses. Choices: `running` `success` `error`
129-
:param sort: List[str] (optional)
130-
Specify how the results are sorted. Choices: `id` `command` `status` `progress` `started` `finished` . You can add one of ":asc", ":desc" to modify sort order. ( ":asc" is default)
131-
:return: List[:class:`BoundAction <hcloud.actions.client.BoundAction>`]
173+
:param status: Filter the Actions by status.
174+
:param sort: Sort Actions by field and direction.
132175
"""
133176
return self._iter_pages(self.get_list, status=status, sort=sort)
134177

@@ -139,8 +182,8 @@ def __init__(self, client: Client):
139182

140183
def get_list(
141184
self,
142-
status: list[str] | None = None,
143-
sort: list[str] | None = None,
185+
status: list[ActionStatus] | None = None,
186+
sort: list[ActionSort] | None = None,
144187
page: int | None = None,
145188
per_page: int | None = None,
146189
) -> ActionsPageResult:
@@ -162,8 +205,8 @@ def get_list(
162205

163206
def get_all(
164207
self,
165-
status: list[str] | None = None,
166-
sort: list[str] | None = None,
208+
status: list[ActionStatus] | None = None,
209+
sort: list[ActionSort] | None = None,
167210
) -> list[BoundAction]:
168211
"""
169212
.. deprecated:: 1.28

hcloud/actions/domain.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING, Any, TypedDict
3+
from typing import TYPE_CHECKING, Any, Literal, TypedDict
44

55
from .._exceptions import HCloudException
66
from ..core import BaseDomain
77

88
if TYPE_CHECKING:
99
from .client import BoundAction
1010

11+
ActionStatus = Literal[
12+
"running",
13+
"success",
14+
"error",
15+
]
16+
1117

1218
class Action(BaseDomain):
1319
"""Action Domain
@@ -45,7 +51,7 @@ def __init__(
4551
self,
4652
id: int,
4753
command: str | None = None,
48-
status: str | None = None,
54+
status: ActionStatus | None = None,
4955
progress: int | None = None,
5056
started: str | None = None,
5157
finished: str | None = None,

0 commit comments

Comments
 (0)