From b31ffcd957d9e431c75d9373cc3567738e47c5bf Mon Sep 17 00:00:00 2001 From: jo Date: Thu, 9 Apr 2026 17:57:10 +0100 Subject: [PATCH] feat(primary-ip): `assignee_type` is optional when creating a primary ip In the create primary IP call, the `assignee_type` argument is now only send when the `assignee_id` argument is set. The `assignee_type` argument will stop defaulting to 'server' in the near future, consider explicitly setting this argument when needed. --- hcloud/primary_ips/client.py | 21 +++++++++++++---- tests/unit/primary_ips/test_client.py | 33 +++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/hcloud/primary_ips/client.py b/hcloud/primary_ips/client.py index 6d6693dc..875032ae 100644 --- a/hcloud/primary_ips/client.py +++ b/hcloud/primary_ips/client.py @@ -311,7 +311,7 @@ def create( name: str, datacenter: Datacenter | BoundDatacenter | None = None, location: Location | BoundLocation | None = None, - assignee_type: str | None = "server", + assignee_type: str | None = None, assignee_id: int | None = None, auto_delete: bool | None = False, labels: dict[str, str] | None = None, @@ -328,13 +328,12 @@ def create( :param labels: Dict[str, str] (optional) User-defined labels (key-value pairs) :return: :class:`CreatePrimaryIPResponse ` """ - data: dict[str, Any] = { "name": name, "type": type, - "assignee_type": assignee_type, "auto_delete": auto_delete, } + if datacenter is not None: warnings.warn( "The 'datacenter' argument is deprecated and will be removed after 1 July 2026. " @@ -348,10 +347,24 @@ def create( data["location"] = location.id_or_name if assignee_id is not None: data["assignee_id"] = assignee_id + if assignee_type is None: + assignee_type = "server" + warnings.warn( + "The 'assignee_type' argument will no longer default to 'server' " + "and will be required together with the 'assignee_id' argument. " + "Please explicitly set the 'assignee_type' argument.", + DeprecationWarning, + stacklevel=2, + ) + data["assignee_type"] = assignee_type if labels is not None: data["labels"] = labels - response = self._client.request(url=self._base_url, json=data, method="POST") + response = self._client.request( + method="POST", + url=self._base_url, + json=data, + ) action = None if response.get("action") is not None: diff --git a/tests/unit/primary_ips/test_client.py b/tests/unit/primary_ips/test_client.py index 04b5fc10..638acb2b 100644 --- a/tests/unit/primary_ips/test_client.py +++ b/tests/unit/primary_ips/test_client.py @@ -162,7 +162,6 @@ def test_create_with_location( json={ "name": "primary-ip1", "type": "ipv4", - "assignee_type": "server", "location": "fsn1", "auto_delete": False, }, @@ -194,7 +193,6 @@ def test_create_with_datacenter( json={ "name": "primary-ip1", "type": "ipv4", - "assignee_type": "server", "datacenter": "fsn1-dc14", "auto_delete": False, }, @@ -236,6 +234,37 @@ def test_create_with_assignee_id( assert_bound_primary_ip1(result.primary_ip, resource_client) assert_bound_action1(result.action, resource_client._parent.actions) + def test_create_with_assignee_type_deprecation( + self, + request_mock: mock.MagicMock, + resource_client: PrimaryIPsClient, + primary_ip1, + action1_running, + ): + request_mock.return_value = { + "primary_ip": primary_ip1, + "action": action1_running, + } + + with pytest.deprecated_call(): + resource_client.create( + type="ipv4", + name="primary-ip1", + assignee_id=17, + ) + + request_mock.assert_called_with( + method="POST", + url="/primary_ips", + json={ + "name": "primary-ip1", + "type": "ipv4", + "assignee_id": 17, + "assignee_type": "server", + "auto_delete": False, + }, + ) + @pytest.mark.parametrize( "primary_ip", [