Skip to content

Commit 9e1883a

Browse files
authored
feat: deprecate datacenters (#656)
The API endpoints `GET /v1/datacenters` and `GET /v1/datacenters/{id}` are now deprecated and will be removed after 1 Oct. 2026. After this date, requests to these endpoints will return `HTTP 410 Gone`. See https://docs.hetzner.cloud/changelog#2026-06-02-datacenters-deprecated.
1 parent b4a2597 commit 9e1883a

9 files changed

Lines changed: 102 additions & 13 deletions

File tree

‎hcloud/_client.py‎

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import time
4+
import warnings
45
from http import HTTPStatus
56
from random import uniform
67
from typing import Any, Protocol
@@ -181,11 +182,10 @@ def __init__(
181182
timeout=timeout,
182183
)
183184

184-
self.datacenters = DatacentersClient(self)
185-
"""DatacentersClient Instance
185+
with warnings.catch_warnings():
186+
warnings.filterwarnings("ignore", category=DeprecationWarning)
187+
self.datacenters = DatacentersClient(self)
186188

187-
:type: :class:`DatacentersClient <hcloud.datacenters.client.DatacentersClient>`
188-
"""
189189
self.locations = LocationsClient(self)
190190
"""LocationsClient Instance
191191
@@ -303,6 +303,28 @@ def request( # type: ignore[no-untyped-def]
303303
"""
304304
return self._client.request(method, url, **kwargs)
305305

306+
@property
307+
def datacenters(self) -> DatacentersClient:
308+
"""DatacentersClient Instance
309+
310+
.. deprecated:: 2.22.0
311+
The datacenters client is deprecated and will be removed after the 2026-10-01.
312+
See https://docs.hetzner.cloud/changelog#2026-06-02-datacenters-deprecated.
313+
314+
:type: :class:`DatacentersClient <hcloud.datacenters.client.DatacentersClient>`
315+
"""
316+
warnings.warn(
317+
"The datacenters client is deprecated and will be removed after the 2026-10-01. "
318+
"See https://docs.hetzner.cloud/changelog#2026-06-02-datacenters-deprecated.",
319+
DeprecationWarning,
320+
stacklevel=2,
321+
)
322+
return self._datacenters
323+
324+
@datacenters.setter
325+
def datacenters(self, value: DatacentersClient) -> None:
326+
self._datacenters = value
327+
306328

307329
class ClientBase:
308330
def __init__(

‎hcloud/core/client.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ def __init__(
109109
"""
110110
self._client = client
111111
self.complete = complete
112-
self.data_model: Domain = self.model.from_dict(data)
112+
113+
with warnings.catch_warnings():
114+
warnings.filterwarnings("ignore", category=DeprecationWarning)
115+
self.data_model: Domain = self.model.from_dict(data)
113116

114117
def __getattr__(self, name: str): # type: ignore[no-untyped-def]
115118
"""Allow magical access to the properties of the model

‎hcloud/datacenters/client.py‎

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
from __future__ import annotations
22

3-
from typing import Any, NamedTuple
3+
import warnings
4+
from typing import TYPE_CHECKING, Any, NamedTuple
45

56
from ..core import BoundModelBase, Meta, ResourceClientBase
67
from ..locations import BoundLocation
78
from ..server_types import BoundServerType
89
from .domain import Datacenter, DatacenterServerTypes
910

11+
if TYPE_CHECKING:
12+
from .._client import Client
13+
1014
__all__ = [
1115
"BoundDatacenter",
1216
"DatacentersPageResult",
@@ -15,6 +19,12 @@
1519

1620

1721
class BoundDatacenter(BoundModelBase[Datacenter], Datacenter):
22+
"""
23+
.. deprecated:: 2.22.0
24+
The bound datacenter class is deprecated and will be removed after the 2026-10-01.
25+
See https://docs.hetzner.cloud/changelog#2026-06-02-datacenters-deprecated.
26+
"""
27+
1828
_client: DatacentersClient
1929

2030
model = Datacenter
@@ -54,13 +64,34 @@ def __init__(self, client: DatacentersClient, data: dict[str, Any]):
5464

5565

5666
class DatacentersPageResult(NamedTuple):
67+
"""
68+
.. deprecated:: 2.22.0
69+
The datacenters page result class is deprecated and will be removed after the 2026-10-01.
70+
See https://docs.hetzner.cloud/changelog#2026-06-02-datacenters-deprecated.
71+
"""
72+
5773
datacenters: list[BoundDatacenter]
5874
meta: Meta
5975

6076

6177
class DatacentersClient(ResourceClientBase):
78+
"""
79+
.. deprecated:: 2.22.0
80+
The datacenters client class is deprecated and will be removed after the 2026-10-01.
81+
See https://docs.hetzner.cloud/changelog#2026-06-02-datacenters-deprecated.
82+
"""
83+
6284
_base_url = "/datacenters"
6385

86+
def __init__(self, client: Client):
87+
warnings.warn(
88+
"The datacenters client class is deprecated and will be removed after the 2026-10-01. "
89+
"See https://docs.hetzner.cloud/changelog#2026-06-02-datacenters-deprecated.",
90+
DeprecationWarning,
91+
stacklevel=2,
92+
)
93+
super().__init__(client)
94+
6495
def get_by_id(self, id: int) -> BoundDatacenter:
6596
"""Get a specific datacenter by its ID.
6697

‎hcloud/datacenters/domain.py‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
class Datacenter(BaseDomain, DomainIdentityMixin):
1919
"""Datacenter Domain
2020
21+
.. deprecated:: 2.22.0
22+
The datacenters domain class is deprecated and will be removed after the 2026-10-01.
23+
See https://docs.hetzner.cloud/changelog#2026-06-02-datacenters-deprecated.
24+
2125
:param id: int ID of Datacenter
2226
:param name: str Name of Datacenter
2327
:param description: str Description of Datacenter
@@ -37,6 +41,12 @@ def __init__(
3741
location: Location | None = None,
3842
server_types: DatacenterServerTypes | None = None,
3943
):
44+
warnings.warn(
45+
"The datacenter domain class is deprecated and will be removed after the 2026-10-01. "
46+
"See https://docs.hetzner.cloud/changelog#2026-06-02-datacenters-deprecated.",
47+
DeprecationWarning,
48+
stacklevel=2,
49+
)
4050
self.id = id
4151
self.name = name
4252
self.description = description
@@ -69,6 +79,10 @@ def server_types(self, value: DatacenterServerTypes | None) -> None:
6979
class DatacenterServerTypes(BaseDomain):
7080
"""DatacenterServerTypes Domain
7181
82+
.. deprecated:: 2.22.0
83+
The datacenters domain class is deprecated and will be removed after the 2026-10-01.
84+
See https://docs.hetzner.cloud/changelog#2026-06-02-datacenters-deprecated.
85+
7286
:param available: List[:class:`BoundServerTypes <hcloud.server_types.client.BoundServerTypes>`]
7387
All available server types for this datacenter
7488
:param supported: List[:class:`BoundServerTypes <hcloud.server_types.client.BoundServerTypes>`]

‎hcloud/primary_ips/client.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ def __init__(
4444

4545
raw = data.get("datacenter", {})
4646
if raw:
47-
data["datacenter"] = BoundDatacenter(client._parent.datacenters, raw)
47+
with warnings.catch_warnings():
48+
warnings.filterwarnings("ignore", category=DeprecationWarning)
49+
data["datacenter"] = BoundDatacenter(client._parent.datacenters, raw)
4850

4951
raw = data.get("location", {})
5052
if raw:

‎hcloud/servers/client.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ def __init__(
7777
):
7878
raw = data.get("datacenter")
7979
if raw:
80-
data["datacenter"] = BoundDatacenter(client._parent.datacenters, raw)
80+
with warnings.catch_warnings():
81+
warnings.filterwarnings("ignore", category=DeprecationWarning)
82+
data["datacenter"] = BoundDatacenter(client._parent.datacenters, raw)
8183

8284
raw = data.get("location")
8385
if raw:

‎tests/unit/actions/test_client.py‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import inspect
4+
import warnings
45
from unittest import mock
56

67
import pytest
@@ -47,10 +48,15 @@ def test_resources_with_actions(client: Client):
4748
"""
4849
Ensure that the list of resource clients above is up to date.
4950
"""
50-
members = inspect.getmembers(
51-
client,
52-
predicate=lambda p: isinstance(p, ResourceClientBase) and hasattr(p, "actions"),
53-
)
51+
with warnings.catch_warnings():
52+
warnings.filterwarnings("ignore", category=DeprecationWarning)
53+
54+
members = inspect.getmembers(
55+
client,
56+
predicate=lambda p: isinstance(p, ResourceClientBase)
57+
and hasattr(p, "actions"),
58+
)
59+
5460
for name, member in members:
5561
assert name in resources_with_actions
5662

‎tests/unit/datacenters/test_client.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import warnings
34
from unittest import mock # noqa: F401
45

56
import pytest # noqa: F401
@@ -8,6 +9,8 @@
89
from hcloud.datacenters import BoundDatacenter, DatacentersClient, DatacenterServerTypes
910
from hcloud.locations import BoundLocation
1011

12+
warnings.filterwarnings("ignore", category=DeprecationWarning)
13+
1114

1215
class TestBoundDatacenter:
1316
def test_bound_datacenter_init(self, datacenter_response):
@@ -64,7 +67,9 @@ def test_bound_datacenter_init(self, datacenter_response):
6467
class TestDatacentersClient:
6568
@pytest.fixture()
6669
def datacenters_client(self, client: Client):
67-
return DatacentersClient(client)
70+
with warnings.catch_warnings():
71+
warnings.filterwarnings("ignore", category=DeprecationWarning)
72+
return DatacentersClient(client)
6873

6974
def test_get_by_id(
7075
self,

‎tests/unit/datacenters/test_domain.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
from __future__ import annotations
22

3+
import warnings
4+
35
import pytest
46

57
from hcloud.datacenters import Datacenter, DatacenterServerTypes
68

9+
warnings.filterwarnings("ignore", category=DeprecationWarning)
10+
711

812
@pytest.mark.parametrize(
913
"value",

0 commit comments

Comments
 (0)