Skip to content

Commit 355aa6c

Browse files
committed
implement actions read endpoints
1 parent 2d1d63c commit 355aa6c

File tree

2 files changed

+192
-1
lines changed

2 files changed

+192
-1
lines changed

hcloud/storage_boxes/client.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from typing import TYPE_CHECKING, Any, NamedTuple
44

5-
from ..actions import BoundAction
5+
from ..actions import ActionsPageResult, BoundAction, ResourceActionsClient
66
from ..core import BoundModelBase, Meta, ResourceClientBase
77
from ..locations import BoundLocation, Location
88
from ..storage_box_types import BoundStorageBoxType, StorageBoxType
@@ -70,9 +70,16 @@ class StorageBoxesClient(ResourceClientBase):
7070
See https://docs.hetzner.cloud/reference/hetzner#storage-boxes.
7171
"""
7272

73+
actions: ResourceActionsClient
74+
"""Storage Boxes scoped actions client
75+
76+
:type: :class:`ResourceActionsClient <hcloud.actions.client.ResourceActionsClient>`
77+
"""
78+
7379
def __init__(self, client: Client):
7480
super().__init__(client)
7581
self._client = client._client_hetzner
82+
self.actions = ResourceActionsClient(self, "/storage_boxes")
7683

7784
def get_by_id(self, id: int) -> BoundStorageBox:
7885
"""
@@ -278,3 +285,66 @@ def get_folders(
278285
)
279286

280287
return StorageBoxFoldersResponse(folders=response["folders"])
288+
289+
def get_actions_list(
290+
self,
291+
storage_box: StorageBox | BoundStorageBox,
292+
*,
293+
status: list[str] | None = None,
294+
sort: list[str] | None = None,
295+
page: int | None = None,
296+
per_page: int | None = None,
297+
) -> ActionsPageResult:
298+
"""
299+
Returns all Actions for a Storage Box for a specific page.
300+
301+
See https://docs.hetzner.cloud/reference/hetzner#storage-box-actions-list-actions-for-a-storage-box
302+
303+
:param storage_box: Storage Box to fetch the Actions from.
304+
:param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
305+
:param sort: Sort resources by field and direction.
306+
:param page: Page number to return.
307+
:param per_page: Maximum number of entries returned per page.
308+
"""
309+
params: dict[str, Any] = {}
310+
if status is not None:
311+
params["status"] = status
312+
if sort is not None:
313+
params["sort"] = sort
314+
if page is not None:
315+
params["page"] = page
316+
if per_page is not None:
317+
params["per_page"] = per_page
318+
319+
response = self._client.request(
320+
method="GET",
321+
url=f"/storage_boxes/{storage_box.id}/actions",
322+
params=params,
323+
)
324+
return ActionsPageResult(
325+
actions=[BoundAction(self._parent.actions, o) for o in response["actions"]],
326+
meta=Meta.parse_meta(response),
327+
)
328+
329+
def get_actions(
330+
self,
331+
storage_box: StorageBox | BoundStorageBox,
332+
*,
333+
status: list[str] | None = None,
334+
sort: list[str] | None = None,
335+
) -> list[BoundAction]:
336+
"""
337+
Returns all Actions for a Storage Box.
338+
339+
See https://docs.hetzner.cloud/reference/hetzner#storage-box-actions-list-actions-for-a-storage-box
340+
341+
:param storage_box: Storage Box to fetch the Actions from.
342+
:param status: Filter the actions by status. The response will only contain actions matching the specified statuses.
343+
:param sort: Sort resources by field and direction.
344+
"""
345+
return self._iter_pages(
346+
self.get_actions_list,
347+
storage_box,
348+
status=status,
349+
sort=sort,
350+
)

tests/unit/storage_boxes/test_client.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,3 +297,124 @@ def test_get_folders(
297297
)
298298

299299
assert result.folders == ["dir1", "dir2"]
300+
301+
# ============ Actions ============
302+
303+
def test_actions_get_by_id(
304+
self,
305+
request_mock: mock.MagicMock,
306+
resource_client: StorageBoxesClient,
307+
action_running1,
308+
):
309+
request_mock.return_value = {
310+
"action": action_running1,
311+
}
312+
313+
result = resource_client.actions.get_by_id(22)
314+
315+
request_mock.assert_called_with(
316+
method="GET",
317+
url="/storage_boxes/actions/22",
318+
)
319+
320+
assert_bound_action(result, resource_client._parent.actions)
321+
322+
def test_actions_get_list(
323+
self,
324+
request_mock: mock.MagicMock,
325+
resource_client: StorageBoxesClient,
326+
action_running1,
327+
):
328+
request_mock.return_value = {
329+
"actions": [action_running1],
330+
}
331+
332+
result = resource_client.actions.get_list()
333+
334+
request_mock.assert_called_with(
335+
method="GET",
336+
url="/storage_boxes/actions",
337+
params={},
338+
)
339+
340+
assert len(result.actions) == 1
341+
assert_bound_action(result.actions[0], resource_client._parent.actions)
342+
343+
@pytest.mark.parametrize(
344+
"params",
345+
[
346+
{"status": "", "sort": ""},
347+
{},
348+
],
349+
)
350+
def test_actions_get_all(
351+
self,
352+
request_mock: mock.MagicMock,
353+
resource_client: StorageBoxesClient,
354+
action_running1,
355+
params,
356+
):
357+
request_mock.return_value = {
358+
"actions": [action_running1],
359+
}
360+
361+
result = resource_client.actions.get_all(**params)
362+
363+
request_mock.assert_called_with(
364+
method="GET",
365+
url="/storage_boxes/actions",
366+
params={**params, "page": 1, "per_page": 50},
367+
)
368+
369+
assert len(result) == 1
370+
assert_bound_action(result[0], resource_client._parent.actions)
371+
372+
def test_get_actions_list(
373+
self,
374+
request_mock: mock.MagicMock,
375+
resource_client: StorageBoxesClient,
376+
action_running1,
377+
):
378+
request_mock.return_value = {
379+
"actions": [action_running1],
380+
}
381+
382+
result = resource_client.get_actions_list(StorageBox(id=42))
383+
384+
request_mock.assert_called_with(
385+
method="GET",
386+
url="/storage_boxes/42/actions",
387+
params={},
388+
)
389+
390+
assert len(result.actions) == 1
391+
assert_bound_action(result.actions[0], resource_client._parent.actions)
392+
393+
@pytest.mark.parametrize(
394+
"params",
395+
[
396+
{"status": "", "sort": ""},
397+
{},
398+
],
399+
)
400+
def test_get_actions(
401+
self,
402+
request_mock: mock.MagicMock,
403+
resource_client: StorageBoxesClient,
404+
action_running1,
405+
params,
406+
):
407+
request_mock.return_value = {
408+
"actions": [action_running1],
409+
}
410+
411+
result = resource_client.get_actions(StorageBox(id=42), **params)
412+
413+
request_mock.assert_called_with(
414+
method="GET",
415+
url="/storage_boxes/42/actions",
416+
params={**params, "page": 1, "per_page": 50},
417+
)
418+
419+
assert len(result) == 1
420+
assert_bound_action(result[0], resource_client._parent.actions)

0 commit comments

Comments
 (0)