Skip to content

Commit c0b18f5

Browse files
committed
feat: add deprecation info to image
1 parent 21b5cdb commit c0b18f5

3 files changed

Lines changed: 44 additions & 10 deletions

File tree

‎hcloud/images/domain.py‎

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

3-
from typing import TYPE_CHECKING, TypedDict
3+
import warnings
4+
from datetime import datetime
5+
from typing import TYPE_CHECKING, Any, TypedDict
46

57
from ..core import BaseDomain, DomainIdentityMixin
8+
from ..deprecation import DeprecationInfo
69

710
if TYPE_CHECKING:
811
from ..actions import BoundAction
@@ -52,8 +55,10 @@ class Image(BaseDomain, DomainIdentityMixin):
5255
Protection configuration for the image
5356
:param deprecated: datetime, None
5457
Point in time when the image is considered to be deprecated (in ISO-8601 format)
58+
:param deprecation:
59+
Describes wether the resources is deprecated.
5560
:param labels: Dict
56-
User-defined labels (key-value pairs)
61+
User-defined labels (key-value pairs)
5762
"""
5863

5964
__api_properties__ = (
@@ -73,11 +78,11 @@ class Image(BaseDomain, DomainIdentityMixin):
7378
"protection",
7479
"labels",
7580
"created",
76-
"deprecated",
81+
"deprecation",
7782
)
7883
__slots__ = __api_properties__
7984

80-
# pylint: disable=too-many-locals
85+
# pylint: disable=too-many-locals,unused-argument
8186
def __init__(
8287
self,
8388
id: int | None = None,
@@ -87,7 +92,7 @@ def __init__(
8792
description: str | None = None,
8893
image_size: int | None = None,
8994
disk_size: int | None = None,
90-
deprecated: str | None = None,
95+
deprecated: str | None = None, # Preserved for backward compatibility
9196
bound_to: Server | BoundServer | None = None,
9297
os_flavor: str | None = None,
9398
os_version: str | None = None,
@@ -97,6 +102,7 @@ def __init__(
97102
protection: ImageProtection | None = None,
98103
labels: dict[str, str] | None = None,
99104
status: str | None = None,
105+
deprecation: dict[str, Any] | None = None,
100106
):
101107
self.id = id
102108
self.name = name
@@ -105,7 +111,6 @@ def __init__(
105111
self.description = description
106112
self.image_size = image_size
107113
self.disk_size = disk_size
108-
self.deprecated = self._parse_datetime(deprecated)
109114
self.bound_to = bound_to
110115
self.os_flavor = os_flavor
111116
self.os_version = os_version
@@ -115,6 +120,27 @@ def __init__(
115120
self.protection = protection
116121
self.labels = labels
117122
self.status = status
123+
self.deprecation = (
124+
None if deprecation is None else DeprecationInfo.from_dict(deprecation)
125+
)
126+
127+
@property
128+
def deprecated(self) -> datetime | None:
129+
"""
130+
.. deprecated:: 2.24.0
131+
The 'deprecated' property is deprecated. Please use to the '.deprecation' property instead.
132+
133+
See https://docs.hetzner.cloud/changelog#2026-09-08-removing-the-deprecated-field.
134+
"""
135+
warnings.warn(
136+
"The 'deprecated' property is deprecated. Please use to the '.deprecation' property instead. "
137+
"See https://docs.hetzner.cloud/changelog#2026-09-08-removing-the-deprecated-field.",
138+
DeprecationWarning,
139+
stacklevel=2,
140+
)
141+
if self.deprecation is None:
142+
return None
143+
return self.deprecation.announced
118144

119145

120146
class ImageProtection(TypedDict):

‎tests/unit/images/conftest.py‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ def image1():
1313
"created": "2021-08-16T11:12:01Z",
1414
"created_from": None,
1515
"deleted": None,
16-
"deprecated": "2026-08-31T06:21:44Z",
16+
"deprecation": {
17+
"announced": "2026-08-31T06:21:44Z",
18+
"unavailable_after": "2026-12-01T00:00:00Z",
19+
},
1720
"description": "Debian 11",
1821
"disk_size": 5,
1922
"image_size": None,
@@ -42,7 +45,7 @@ def image2():
4245
"name": "server1",
4346
},
4447
"deleted": None,
45-
"deprecated": None,
48+
"deprecation": None,
4649
"description": "snapshot 2026-09-08T13:44:08Z",
4750
"disk_size": 80,
4851
"image_size": 0.7237785009765625,

‎tests/unit/images/test_client.py‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ def test_init(self, image1, image2):
6464
assert o.rapid_deploy is True
6565
assert o.labels == {}
6666
assert o.protection == {"delete": False}
67-
assert o.deprecated == isoparse("2026-08-31T06:21:44Z")
67+
with pytest.deprecated_call():
68+
assert o.deprecated == isoparse("2026-08-31T06:21:44Z")
69+
assert o.deprecation.announced == isoparse("2026-08-31T06:21:44Z")
70+
assert o.deprecation.unavailable_after == isoparse("2026-12-01T00:00:00Z")
6871

6972
o = BoundImage(client=mock.MagicMock(), data=image2)
7073

@@ -87,7 +90,9 @@ def test_init(self, image1, image2):
8790
assert o.rapid_deploy is False
8891
assert o.labels == {"key": "value"}
8992
assert o.protection == {"delete": True}
90-
assert o.deprecated is None
93+
with pytest.deprecated_call():
94+
assert o.deprecated is None
95+
assert o.deprecation is None
9196

9297

9398
class TestImagesClient:

0 commit comments

Comments
 (0)