Skip to content

Commit 34ba176

Browse files
committed
feat: deprecate datacenter in primary ips and servers
See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters
1 parent 9e7cd39 commit 34ba176

File tree

4 files changed

+109
-13
lines changed

4 files changed

+109
-13
lines changed

hcloud/primary_ips/client.py

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

3+
import warnings
34
from typing import TYPE_CHECKING, Any, NamedTuple
45

56
from ..actions import BoundAction, ResourceActionsClient
@@ -9,6 +10,7 @@
910
if TYPE_CHECKING:
1011
from .._client import Client
1112
from ..datacenters import BoundDatacenter, Datacenter
13+
from ..locations import BoundLocation, Location
1214

1315

1416
class BoundPrimaryIP(BoundModelBase, PrimaryIP):
@@ -19,10 +21,15 @@ class BoundPrimaryIP(BoundModelBase, PrimaryIP):
1921
def __init__(self, client: PrimaryIPsClient, data: dict, complete: bool = True):
2022
# pylint: disable=import-outside-toplevel
2123
from ..datacenters import BoundDatacenter
24+
from ..locations import BoundLocation
2225

23-
datacenter = data.get("datacenter", {})
24-
if datacenter:
25-
data["datacenter"] = BoundDatacenter(client._parent.datacenters, datacenter)
26+
raw = data.get("datacenter", {})
27+
if raw:
28+
data["datacenter"] = BoundDatacenter(client._parent.datacenters, raw)
29+
30+
raw = data.get("location", {})
31+
if raw:
32+
data["location"] = BoundLocation(client._parent.locations, raw)
2633

2734
super().__init__(client, data, complete)
2835

@@ -196,6 +203,7 @@ def create(
196203
type: str,
197204
name: str,
198205
datacenter: Datacenter | BoundDatacenter | None = None,
206+
location: Location | BoundLocation | None = None,
199207
assignee_type: str | None = "server",
200208
assignee_id: int | None = None,
201209
auto_delete: bool | None = False,
@@ -206,6 +214,7 @@ def create(
206214
:param type: str Primary IP type Choices: ipv4, ipv6
207215
:param name: str
208216
:param datacenter: Datacenter (optional)
217+
:param location: Location (optional)
209218
:param assignee_type: str (optional)
210219
:param assignee_id: int (optional)
211220
:param auto_delete: bool (optional)
@@ -220,7 +229,16 @@ def create(
220229
"auto_delete": auto_delete,
221230
}
222231
if datacenter is not None:
232+
warnings.warn(
233+
"The 'datacenter' argument is deprecated and will be removed after 1 July 2026. "
234+
"Please use the 'location' argument instead. "
235+
"See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters",
236+
DeprecationWarning,
237+
stacklevel=2,
238+
)
223239
data["datacenter"] = datacenter.id_or_name
240+
if location is not None:
241+
data["location"] = location.id_or_name
224242
if assignee_id is not None:
225243
data["assignee_id"] = assignee_id
226244
if labels is not None:

hcloud/primary_ips/domain.py

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

3+
import warnings
34
from typing import TYPE_CHECKING
45

56
from dateutil.parser import isoparse
@@ -9,6 +10,7 @@
910
if TYPE_CHECKING:
1011
from ..actions import BoundAction
1112
from ..datacenters import BoundDatacenter
13+
from ..locations import BoundLocation
1214
from .client import BoundPrimaryIP
1315

1416

@@ -25,6 +27,8 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
2527
Array of reverse DNS entries
2628
:param datacenter: :class:`Datacenter <hcloud.datacenters.client.BoundDatacenter>`
2729
Datacenter the Primary IP was created in.
30+
:param location: :class:`Location <hcloud.locations.client.BoundLocation>`
31+
Location the Primary IP was created in.
2832
:param blocked: boolean
2933
Whether the IP is blocked
3034
:param protection: dict
@@ -43,12 +47,11 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
4347
Delete the Primary IP when the Assignee it is assigned to is deleted.
4448
"""
4549

46-
__api_properties__ = (
50+
__properties__ = (
4751
"id",
4852
"ip",
4953
"type",
5054
"dns_ptr",
51-
"datacenter",
5255
"blocked",
5356
"protection",
5457
"labels",
@@ -58,7 +61,14 @@ class PrimaryIP(BaseDomain, DomainIdentityMixin):
5861
"assignee_type",
5962
"auto_delete",
6063
)
61-
__slots__ = __api_properties__
64+
__api_properties__ = (
65+
*__properties__,
66+
"datacenter",
67+
)
68+
__slots__ = (
69+
*__properties__,
70+
"_datacenter",
71+
)
6272

6373
def __init__(
6474
self,
@@ -67,6 +77,7 @@ def __init__(
6777
ip: str | None = None,
6878
dns_ptr: list[dict] | None = None,
6979
datacenter: BoundDatacenter | None = None,
80+
location: BoundLocation | None = None,
7081
blocked: bool | None = None,
7182
protection: dict | None = None,
7283
labels: dict[str, dict] | None = None,
@@ -81,6 +92,7 @@ def __init__(
8192
self.ip = ip
8293
self.dns_ptr = dns_ptr
8394
self.datacenter = datacenter
95+
self.location = location
8496
self.blocked = blocked
8597
self.protection = protection
8698
self.labels = labels
@@ -90,6 +102,27 @@ def __init__(
90102
self.assignee_type = assignee_type
91103
self.auto_delete = auto_delete
92104

105+
@property
106+
def datacenter(self) -> BoundDatacenter | None:
107+
"""
108+
Datacenter the Primary IP was created in.
109+
110+
.. deprecated:: 2.13
111+
See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters
112+
"""
113+
warnings.warn(
114+
"The 'datacenter' property is deprecated and will be removed after 1 July 2026. "
115+
"Please use the 'location' property instead. "
116+
"",
117+
DeprecationWarning,
118+
stacklevel=2,
119+
)
120+
return self._datacenter
121+
122+
@datacenter.setter
123+
def datacenter(self, value: BoundDatacenter | None) -> None:
124+
self._datacenter = value
125+
93126

94127
class CreatePrimaryIPResponse(BaseDomain):
95128
"""Create Primary IP Response Domain

hcloud/servers/client.py

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

3+
import warnings
34
from datetime import datetime
45
from typing import TYPE_CHECKING, Any, NamedTuple
56

@@ -12,6 +13,7 @@
1213
from ..floating_ips import BoundFloatingIP
1314
from ..images import BoundImage, CreateImageResponse
1415
from ..isos import BoundIso
16+
from ..locations import BoundLocation, Location
1517
from ..metrics import Metrics
1618
from ..placement_groups import BoundPlacementGroup
1719
from ..primary_ips import BoundPrimaryIP
@@ -39,7 +41,6 @@
3941
from ..firewalls import Firewall
4042
from ..images import Image
4143
from ..isos import Iso
42-
from ..locations import BoundLocation, Location
4344
from ..networks import BoundNetwork, Network
4445
from ..placement_groups import PlacementGroup
4546
from ..server_types import ServerType
@@ -55,9 +56,13 @@ class BoundServer(BoundModelBase, Server):
5556

5657
# pylint: disable=too-many-locals
5758
def __init__(self, client: ServersClient, data: dict, complete: bool = True):
58-
datacenter = data.get("datacenter")
59-
if datacenter is not None:
60-
data["datacenter"] = BoundDatacenter(client._parent.datacenters, datacenter)
59+
raw = data.get("datacenter")
60+
if raw:
61+
data["datacenter"] = BoundDatacenter(client._parent.datacenters, raw)
62+
63+
raw = data.get("location")
64+
if raw:
65+
data["location"] = BoundLocation(client._parent.locations, raw)
6166

6267
volumes = data.get("volumes", [])
6368
if volumes:
@@ -657,6 +662,13 @@ def create(
657662
if location is not None:
658663
data["location"] = location.id_or_name
659664
if datacenter is not None:
665+
warnings.warn(
666+
"The 'datacenter' argument is deprecated and will be removed after 1 July 2026. "
667+
"Please use the 'location' argument instead. "
668+
"See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters",
669+
DeprecationWarning,
670+
stacklevel=2,
671+
)
660672
data["datacenter"] = datacenter.id_or_name
661673
if ssh_keys is not None:
662674
data["ssh_keys"] = [ssh_key.id_or_name for ssh_key in ssh_keys]

hcloud/servers/domain.py

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

3+
import warnings
34
from typing import TYPE_CHECKING, Literal
45

56
from dateutil.parser import isoparse
@@ -13,6 +14,7 @@
1314
from ..floating_ips import BoundFloatingIP
1415
from ..images import BoundImage
1516
from ..isos import BoundIso
17+
from ..locations import BoundLocation
1618
from ..metrics import Metrics
1719
from ..networks import BoundNetwork, Network
1820
from ..placement_groups import BoundPlacementGroup
@@ -37,6 +39,7 @@ class Server(BaseDomain, DomainIdentityMixin):
3739
Public network information.
3840
:param server_type: :class:`BoundServerType <hcloud.server_types.client.BoundServerType>`
3941
:param datacenter: :class:`BoundDatacenter <hcloud.datacenters.client.BoundDatacenter>`
42+
:param location: :class:`BoundLocation <hcloud.locations.client.BoundLocation>`
4043
:param image: :class:`BoundImage <hcloud.images.client.BoundImage>`, None
4144
:param iso: :class:`BoundIso <hcloud.isos.client.BoundIso>`, None
4245
:param rescue_enabled: bool
@@ -82,13 +85,13 @@ class Server(BaseDomain, DomainIdentityMixin):
8285
STATUS_UNKNOWN = "unknown"
8386
"""Server Status unknown"""
8487

85-
__api_properties__ = (
88+
__properties__ = (
8689
"id",
8790
"name",
8891
"status",
8992
"public_net",
9093
"server_type",
91-
"datacenter",
94+
"location",
9295
"image",
9396
"iso",
9497
"rescue_enabled",
@@ -105,7 +108,14 @@ class Server(BaseDomain, DomainIdentityMixin):
105108
"primary_disk_size",
106109
"placement_group",
107110
)
108-
__slots__ = __api_properties__
111+
__api_properties__ = (
112+
*__properties__,
113+
"datacenter",
114+
)
115+
__slots__ = (
116+
*__properties__,
117+
"_datacenter",
118+
)
109119

110120
# pylint: disable=too-many-locals
111121
def __init__(
@@ -117,6 +127,7 @@ def __init__(
117127
public_net: PublicNetwork | None = None,
118128
server_type: BoundServerType | None = None,
119129
datacenter: BoundDatacenter | None = None,
130+
location: BoundLocation | None = None,
120131
image: BoundImage | None = None,
121132
iso: BoundIso | None = None,
122133
rescue_enabled: bool | None = None,
@@ -139,6 +150,7 @@ def __init__(
139150
self.public_net = public_net
140151
self.server_type = server_type
141152
self.datacenter = datacenter
153+
self.location = location
142154
self.image = image
143155
self.iso = iso
144156
self.rescue_enabled = rescue_enabled
@@ -164,6 +176,27 @@ def private_net_for(self, network: BoundNetwork | Network) -> PrivateNet | None:
164176
return o
165177
return None
166178

179+
@property
180+
def datacenter(self) -> BoundDatacenter | None:
181+
"""
182+
Datacenter the Server was created in.
183+
184+
.. deprecated:: 2.13
185+
See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters
186+
"""
187+
warnings.warn(
188+
"The 'datacenter' property is deprecated and will be removed after 1 July 2026. "
189+
"Please use the 'location' property instead. "
190+
"See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters",
191+
DeprecationWarning,
192+
stacklevel=2,
193+
)
194+
return self._datacenter
195+
196+
@datacenter.setter
197+
def datacenter(self, value: BoundDatacenter | None) -> None:
198+
self._datacenter = value
199+
167200

168201
class CreateServerResponse(BaseDomain):
169202
"""Create Server Response Domain

0 commit comments

Comments
 (0)