Skip to content

Commit 48551da

Browse files
jooolaapricote
andauthored
feat: add support for Storage Boxes (#524)
We collect all changes for the Storage Box support in this PR. It will only be merged when everything is implemented through smaller pull requests targeting the `storage-boxes` branch. Implements https://docs.hetzner.cloud/reference/hetzner#storage-boxes Closes #526 --------- Co-authored-by: Julian Tölle <julian.toelle@hetzner-cloud.de>
1 parent 79ffad3 commit 48551da

File tree

19 files changed

+4229
-2
lines changed

19 files changed

+4229
-2
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
StorageBoxTypesClient
2+
=====================
3+
4+
.. autoclass:: hcloud.storage_box_types.client.StorageBoxTypesClient
5+
:members:
6+
7+
.. autoclass:: hcloud.storage_box_types.client.StorageBoxTypesPageResult
8+
:members:
9+
10+
.. autoclass:: hcloud.storage_box_types.client.BoundStorageBoxType
11+
:members:
12+
13+
.. autoclass:: hcloud.storage_box_types.domain.StorageBoxType
14+
:members:

docs/api.clients.storage_boxes.rst

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
StorageBoxesClient
2+
=====================
3+
4+
.. autoclass:: hcloud.storage_boxes.client.StorageBoxesClient
5+
:members:
6+
7+
.. autoclass:: hcloud.storage_boxes.client.StorageBoxesPageResult
8+
:members:
9+
10+
.. autoclass:: hcloud.storage_boxes.client.StorageBoxSnapshotsPageResult
11+
:members:
12+
13+
.. autoclass:: hcloud.storage_boxes.client.StorageBoxSubaccountsPageResult
14+
:members:
15+
16+
.. autoclass:: hcloud.storage_boxes.client.BoundStorageBox
17+
:members:
18+
19+
.. autoclass:: hcloud.storage_boxes.client.BoundStorageBoxSnapshot
20+
:members:
21+
22+
.. autoclass:: hcloud.storage_boxes.client.BoundStorageBoxSubaccount
23+
:members:
24+
25+
26+
.. autoclass:: hcloud.storage_boxes.domain.StorageBox
27+
:members:
28+
29+
.. autoclass:: hcloud.storage_boxes.domain.StorageBoxAccessSettings
30+
:members:
31+
32+
.. autoclass:: hcloud.storage_boxes.domain.StorageBoxSnapshotPlan
33+
:members:
34+
35+
.. autoclass:: hcloud.storage_boxes.domain.StorageBoxStats
36+
:members:
37+
38+
.. autoclass:: hcloud.storage_boxes.domain.StorageBoxStatus
39+
:members:
40+
41+
42+
.. autoclass:: hcloud.storage_boxes.domain.StorageBoxSnapshot
43+
:members:
44+
45+
.. autoclass:: hcloud.storage_boxes.domain.StorageBoxSnapshotStats
46+
:members:
47+
48+
49+
.. autoclass:: hcloud.storage_boxes.domain.StorageBoxSubaccount
50+
:members:
51+
52+
.. autoclass:: hcloud.storage_boxes.domain.StorageBoxSubaccountAccessSettings
53+
:members:
54+
55+
56+
.. autoclass:: hcloud.storage_boxes.domain.CreateStorageBoxResponse
57+
:members:
58+
59+
.. autoclass:: hcloud.storage_boxes.domain.CreateStorageBoxSnapshotResponse
60+
:members:
61+
62+
.. autoclass:: hcloud.storage_boxes.domain.CreateStorageBoxSubaccountResponse
63+
:members:
64+
65+
.. autoclass:: hcloud.storage_boxes.domain.StorageBoxFoldersResponse
66+
:members:
67+
68+
.. autoclass:: hcloud.storage_boxes.domain.DeleteStorageBoxResponse
69+
:members:
70+
71+
.. autoclass:: hcloud.storage_boxes.domain.DeleteStorageBoxSnapshotResponse
72+
:members:
73+
74+
.. autoclass:: hcloud.storage_boxes.domain.DeleteStorageBoxSubaccountResponse
75+
:members:

hcloud/_client.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
from .server_types import ServerTypesClient
2626
from .servers import ServersClient
2727
from .ssh_keys import SSHKeysClient
28+
from .storage_box_types import StorageBoxTypesClient
29+
from .storage_boxes import StorageBoxesClient
2830
from .volumes import VolumesClient
2931
from .zones import ZonesClient
3032

@@ -141,11 +143,14 @@ def __init__(
141143
poll_interval: int | float | BackoffFunction = 1.0,
142144
poll_max_retries: int = 120,
143145
timeout: float | tuple[float, float] | None = None,
146+
*,
147+
api_endpoint_hetzner: str = "https://api.hetzner.com/v1",
144148
):
145149
"""Create a new Client instance
146150
147151
:param token: Hetzner Cloud API token
148152
:param api_endpoint: Hetzner Cloud API endpoint
153+
:param api_endpoint_hetzner: Hetzner API endpoint.
149154
:param application_name: Your application name
150155
:param application_version: Your application _version
151156
:param poll_interval:
@@ -164,6 +169,15 @@ def __init__(
164169
poll_max_retries=poll_max_retries,
165170
timeout=timeout,
166171
)
172+
self._client_hetzner = ClientBase(
173+
token=token,
174+
endpoint=api_endpoint_hetzner,
175+
application_name=application_name,
176+
application_version=application_version,
177+
poll_interval=poll_interval,
178+
poll_max_retries=poll_max_retries,
179+
timeout=timeout,
180+
)
167181

168182
self.datacenters = DatacentersClient(self)
169183
"""DatacentersClient Instance
@@ -261,6 +275,18 @@ def __init__(
261275
:type: :class:`ZonesClient <hcloud.zones.client.ZonesClient>`
262276
"""
263277

278+
self.storage_box_types = StorageBoxTypesClient(self)
279+
"""StorageBoxTypesClient Instance
280+
281+
:type: :class:`StorageBoxTypesClient <hcloud.storage_box_types.client.StorageBoxTypesClient>`
282+
"""
283+
284+
self.storage_boxes = StorageBoxesClient(self)
285+
"""StorageBoxesClient Instance
286+
287+
:type: :class:`StorageBoxesClient <hcloud.storage_boxes.client.StorageBoxesClient>`
288+
"""
289+
264290
def request( # type: ignore[no-untyped-def]
265291
self,
266292
method: str,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from __future__ import annotations
2+
3+
from .client import (
4+
BoundStorageBoxType,
5+
StorageBoxTypesClient,
6+
StorageBoxTypesPageResult,
7+
)
8+
from .domain import StorageBoxType
9+
10+
__all__ = [
11+
"BoundStorageBoxType",
12+
"StorageBoxType",
13+
"StorageBoxTypesClient",
14+
"StorageBoxTypesPageResult",
15+
]

hcloud/storage_box_types/client.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING, Any, NamedTuple
4+
5+
from ..core import BoundModelBase, Meta, ResourceClientBase
6+
from .domain import StorageBoxType
7+
8+
if TYPE_CHECKING:
9+
from .._client import Client
10+
11+
12+
class BoundStorageBoxType(BoundModelBase, StorageBoxType):
13+
_client: StorageBoxTypesClient
14+
15+
model = StorageBoxType
16+
17+
18+
class StorageBoxTypesPageResult(NamedTuple):
19+
storage_box_types: list[BoundStorageBoxType]
20+
meta: Meta
21+
22+
23+
class StorageBoxTypesClient(ResourceClientBase):
24+
"""
25+
A client for the Storage Box Types API.
26+
27+
See https://docs.hetzner.cloud/reference/hetzner#storage-box-types.
28+
29+
Experimental:
30+
Storage Box support is experimental, breaking changes may occur within minor releases.
31+
"""
32+
33+
_base_url = "/storage_box_types"
34+
35+
def __init__(self, client: Client):
36+
super().__init__(client)
37+
self._client = client._client_hetzner
38+
39+
def get_by_id(self, id: int) -> BoundStorageBoxType:
40+
"""
41+
Returns a specific Storage Box Type.
42+
43+
See https://docs.hetzner.cloud/reference/hetzner#storage-box-types-get-a-storage-box-type
44+
45+
:param id: ID of the Storage Box Type.
46+
47+
Experimental:
48+
Storage Box support is experimental, breaking changes may occur within minor releases.
49+
"""
50+
response = self._client.request(
51+
method="GET",
52+
url=f"{self._base_url}/{id}",
53+
)
54+
return BoundStorageBoxType(self, response["storage_box_type"])
55+
56+
def get_by_name(self, name: str) -> BoundStorageBoxType | None:
57+
"""
58+
Returns a specific Storage Box Type.
59+
60+
See https://docs.hetzner.cloud/reference/hetzner#storage-box-types-list-storage-box-types
61+
62+
:param name: Name of the Storage Box Type.
63+
64+
Experimental:
65+
Storage Box support is experimental, breaking changes may occur within minor releases.
66+
"""
67+
return self._get_first_by(self.get_list, name=name)
68+
69+
def get_list(
70+
self,
71+
name: str | None = None,
72+
page: int | None = None,
73+
per_page: int | None = None,
74+
) -> StorageBoxTypesPageResult:
75+
"""
76+
Returns a list of Storage Box Types for a specific page.
77+
78+
See https://docs.hetzner.cloud/reference/hetzner#storage-box-types-list-storage-box-types
79+
80+
:param name: Name of the Storage Box Type.
81+
:param page: Page number to return.
82+
:param per_page: Maximum number of entries returned per page.
83+
84+
Experimental:
85+
Storage Box support is experimental, breaking changes may occur within minor releases.
86+
"""
87+
params: dict[str, Any] = {}
88+
if name is not None:
89+
params["name"] = name
90+
if page is not None:
91+
params["page"] = page
92+
if per_page is not None:
93+
params["per_page"] = per_page
94+
95+
response = self._client.request(
96+
method="GET",
97+
url=f"{self._base_url}",
98+
params=params,
99+
)
100+
return StorageBoxTypesPageResult(
101+
storage_box_types=[
102+
BoundStorageBoxType(self, o) for o in response["storage_box_types"]
103+
],
104+
meta=Meta.parse_meta(response),
105+
)
106+
107+
def get_all(
108+
self,
109+
name: str | None = None,
110+
) -> list[BoundStorageBoxType]:
111+
"""
112+
Returns all Storage Box Types.
113+
114+
See https://docs.hetzner.cloud/reference/hetzner#storage-box-types-list-storage-box-types
115+
116+
:param name: Name of the Storage Box Type.
117+
118+
Experimental:
119+
Storage Box support is experimental, breaking changes may occur within minor releases.
120+
"""
121+
return self._iter_pages(
122+
self.get_list,
123+
name=name,
124+
)

hcloud/storage_box_types/domain.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from __future__ import annotations
2+
3+
from ..core import BaseDomain, DomainIdentityMixin
4+
from ..deprecation import DeprecationInfo
5+
6+
7+
class StorageBoxType(BaseDomain, DomainIdentityMixin):
8+
"""
9+
Storage Box Type Domain.
10+
11+
See https://docs.hetzner.cloud/reference/hetzner#storage-box-types.
12+
"""
13+
14+
__api_properties__ = (
15+
"id",
16+
"name",
17+
"description",
18+
"snapshot_limit",
19+
"automatic_snapshot_limit",
20+
"subaccounts_limit",
21+
"size",
22+
"deprecation",
23+
"prices",
24+
)
25+
__slots__ = __api_properties__
26+
27+
def __init__(
28+
self,
29+
id: int | None = None,
30+
name: str | None = None,
31+
description: str | None = None,
32+
snapshot_limit: int | None = None,
33+
automatic_snapshot_limit: int | None = None,
34+
subaccounts_limit: int | None = None,
35+
size: int | None = None,
36+
prices: list[dict] | None = None,
37+
deprecation: dict | None = None,
38+
):
39+
self.id = id
40+
self.name = name
41+
self.description = description
42+
self.snapshot_limit = snapshot_limit
43+
self.automatic_snapshot_limit = automatic_snapshot_limit
44+
self.subaccounts_limit = subaccounts_limit
45+
self.size = size
46+
self.prices = prices
47+
self.deprecation = (
48+
DeprecationInfo.from_dict(deprecation) if deprecation is not None else None
49+
)

hcloud/storage_boxes/__init__.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from __future__ import annotations
2+
3+
from .client import (
4+
BoundStorageBox,
5+
BoundStorageBoxSnapshot,
6+
BoundStorageBoxSubaccount,
7+
StorageBoxesClient,
8+
StorageBoxesPageResult,
9+
StorageBoxSnapshotsPageResult,
10+
StorageBoxSubaccountsPageResult,
11+
)
12+
from .domain import (
13+
CreateStorageBoxResponse,
14+
CreateStorageBoxSnapshotResponse,
15+
CreateStorageBoxSubaccountResponse,
16+
DeleteStorageBoxResponse,
17+
DeleteStorageBoxSnapshotResponse,
18+
DeleteStorageBoxSubaccountResponse,
19+
StorageBox,
20+
StorageBoxAccessSettings,
21+
StorageBoxFoldersResponse,
22+
StorageBoxSnapshot,
23+
StorageBoxSnapshotPlan,
24+
StorageBoxSnapshotStats,
25+
StorageBoxStats,
26+
StorageBoxStatus,
27+
StorageBoxSubaccount,
28+
StorageBoxSubaccountAccessSettings,
29+
)
30+
31+
__all__ = [
32+
"BoundStorageBox",
33+
"BoundStorageBoxSnapshot",
34+
"BoundStorageBoxSubaccount",
35+
"CreateStorageBoxResponse",
36+
"CreateStorageBoxSnapshotResponse",
37+
"CreateStorageBoxSubaccountResponse",
38+
"DeleteStorageBoxResponse",
39+
"DeleteStorageBoxSnapshotResponse",
40+
"DeleteStorageBoxSubaccountResponse",
41+
"StorageBox",
42+
"StorageBoxAccessSettings",
43+
"StorageBoxesClient",
44+
"StorageBoxesPageResult",
45+
"StorageBoxFoldersResponse",
46+
"StorageBoxSnapshot",
47+
"StorageBoxSnapshotPlan",
48+
"StorageBoxSnapshotsPageResult",
49+
"StorageBoxSnapshotStats",
50+
"StorageBoxStats",
51+
"StorageBoxStatus",
52+
"StorageBoxSubaccount",
53+
"StorageBoxSubaccountAccessSettings",
54+
"StorageBoxSubaccountsPageResult",
55+
]

0 commit comments

Comments
 (0)