Skip to content

Commit 9e89f7b

Browse files
authored
feat: add update mixin for API objects (#32)
Add `transip.mixins.ObjectUpdateMixin` for calling `update()` on API objects directly to update instances. Signed-off-by: Roald Nefs <info@roaldnefs.com>
1 parent 5faa0a7 commit 9e89f7b

5 files changed

Lines changed: 54 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ All notable changes in **python-transip** are documented below.
66
- This `CHANGELOG.md` file to be able to list all notable changes for each version of **python-transip**.
77
- The `transip.v6.objects.ApiTestService` service to allow calling the test resource to make sure everything is working.
88
- The `transip.v6.objects.InvoiceItemService` service to allow listing all invoice items on a `transip.v6.objects.Invoice` object.
9+
- The `transip.mixins.ObjectUpdateMixin` mixin to allow calling `update()` on API object directly.
910

1011
[Unreleased]: https://github.com/roaldnefs/python-transip/compare/v0.3.0...HEAD

tests/services/test_ssh_keys.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,23 @@ def test_delete(self) -> None:
6565

6666
@responses.activate
6767
def test_delete_object(self) -> None:
68-
ssh_key_id: int = 123
69-
ssh_key: SshKey = self.client.ssh_keys.get(ssh_key_id) # type: ignore
68+
ssh_key: SshKey = self.client.ssh_keys.get(123) # type: ignore
7069

7170
try:
7271
ssh_key.delete() # type: ignore
7372
except Exception as exc:
7473
assert False, f"'transip.v6.objects.SshKey.delete' raised an exception {exc}"
7574

75+
@responses.activate
76+
def test_update_object(self) -> None:
77+
ssh_key: SshKey = self.client.ssh_keys.get(123) # type: ignore
78+
ssh_key.description = "Jim key"
79+
80+
try:
81+
ssh_key.update()
82+
except Exception as exc:
83+
assert False, f"'transip.v6.objects.SshKey.update' raised an exception {exc}"
84+
7685
@responses.activate
7786
def test_create(self) -> None:
7887
ssh_key_data: Dict[str, str] = {

transip/base.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,21 @@ def __init__(self, service, attrs) -> None:
3232
{
3333
"service": service,
3434
"_attrs": attrs,
35+
"_updated_attrs": {}
3536
}
3637
)
3738

3839
def __getattr__(self, name: str) -> Any:
3940
try:
40-
return self.__dict__["_attrs"][name]
41+
return self.__dict__["_updated_attrs"][name]
4142
except KeyError:
42-
raise AttributeError(name)
43+
try:
44+
return self.__dict__["_attrs"][name]
45+
except KeyError:
46+
raise AttributeError(name)
4347

4448
def __setattr__(self, name: str, value: Any) -> None:
45-
self.__dict__["_attrs"][name] = value
49+
self.__dict__["_updated_attrs"][name] = value
4650

4751
def __str__(self) -> str:
4852
return f"{type(self)} => {self._attrs}"
@@ -65,7 +69,12 @@ def get_id(self) -> Any:
6569

6670
@property
6771
def attrs(self):
68-
return self.__dict__["_attrs"]
72+
"""
73+
Returns a dictionary containing all the attributes.
74+
"""
75+
attrs = self.__dict__["_updated_attrs"].copy()
76+
attrs.update(self.__dict__["_attrs"])
77+
return attrs
6978

7079

7180
class ApiService:

transip/mixins.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,33 @@ def delete(self) -> None:
7777
self.service.delete(self.get_id()) # type: ignore
7878

7979

80+
class ObjectUpdateMixin:
81+
"""Update a single ApiObject."""
82+
83+
service: ApiService
84+
_updated_attrs: Any
85+
86+
def _get_updated_data(self) -> Union[Dict, Dict[str, Any]]:
87+
updated_data = {}
88+
required, optional = self.service.get_update_attrs() # type: ignore
89+
# Add all required attributes, even if they haven't been updated
90+
for attr in required:
91+
updated_data[attr] = getattr(self, attr)
92+
updated_data.update(self._updated_attrs)
93+
return updated_data
94+
95+
def update(self) -> None:
96+
"""
97+
Update the changes made to the object.
98+
"""
99+
updated_data = self._get_updated_data()
100+
if not updated_data:
101+
return
102+
103+
obj_id = self.get_id() # type: ignore
104+
self.service.update(obj_id, updated_data) # type: ignore
105+
106+
80107
class ListMixin:
81108
"""
82109
Retrieve a list of ApiObjects.

transip/v6/objects.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from transip.base import ApiService, ApiObject
2323
from transip.mixins import (
2424
GetMixin, DeleteMixin, ListMixin, CreateMixin, UpdateMixin,
25-
ObjectDeleteMixin,
25+
ObjectDeleteMixin, ObjectUpdateMixin,
2626
CreateAttrsTuple, UpdateAttrsTuple
2727
)
2828

@@ -57,7 +57,7 @@ class AvailabilityZoneService(ListMixin, ApiService):
5757
_resp_list_attr: str = "availabilityZones"
5858

5959

60-
class SshKey(ObjectDeleteMixin, ApiObject):
60+
class SshKey(ObjectDeleteMixin, ObjectUpdateMixin, ApiObject):
6161

6262
_id_attr: str = "id"
6363

0 commit comments

Comments
 (0)