Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang

<!-- towncrier release notes start -->

## [1.9.1](https://github.com/opsmill/infrahub-sdk-python/tree/v1.9.1) - 2025-04-04
## [1.10.2](https://github.com/opsmill/infrahub-sdk-python/tree/v1.10.2) - 2025-04-11

### Fixed

- fix an issue where nodes attributes were not updated when setting the same value than the one used during node instantiation
- fixes an issue where the default branch of the client store was not properly set in a generator

## [1.10.1](https://github.com/opsmill/infrahub-sdk-python/tree/v1.9.1) - 2025-04-04

### Changed

Expand Down
1 change: 1 addition & 0 deletions infrahub_sdk/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def __init__(
self.generator_instance = generator_instance
self._init_client = client.clone()
self._init_client.config.default_branch = self._init_client.default_branch = self.branch_name
self._init_client.store._default_branch = self.branch_name
self._client: InfrahubClient | None = None
self._nodes: list[InfrahubNode] = []
self._related_nodes: list[InfrahubNode] = []
Expand Down
20 changes: 16 additions & 4 deletions infrahub_sdk/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,18 @@ def __init__(self, name: str, schema: AttributeSchemaAPI, data: Any | dict):

self.id: str | None = data.get("id", None)

self.value: Any | None = data.get("value", None)
self._value: Any | None = data.get("value", None)
self.value_has_been_mutated = False
self.is_default: bool | None = data.get("is_default", None)
self.is_from_profile: bool | None = data.get("is_from_profile", None)

if self.value:
if self._value:
value_mapper: dict[str, Callable] = {
"IPHost": ipaddress.ip_interface,
"IPNetwork": ipaddress.ip_network,
}
mapper = value_mapper.get(schema.kind, lambda value: value)
self.value = mapper(data.get("value"))
self._value = mapper(data.get("value"))

self.is_inherited: bool | None = data.get("is_inherited", None)
self.updated_at: str | None = data.get("updated_at", None)
Expand All @@ -107,6 +108,15 @@ def __init__(self, name: str, schema: AttributeSchemaAPI, data: Any | dict):
if data.get(prop_name):
setattr(self, prop_name, NodeProperty(data=data.get(prop_name))) # type: ignore[arg-type]

@property
def value(self) -> Any:
return self._value

@value.setter
def value(self, value: Any) -> None:
self._value = value
self.value_has_been_mutated = True

def _generate_input_data(self) -> dict | None:
data: dict[str, Any] = {}
variables: dict[str, Any] = {}
Expand Down Expand Up @@ -975,7 +985,9 @@ def _strip_unmodified(self, data: dict, variables: dict) -> tuple[dict, dict]:
for item in original_data.keys():
if item in data.keys():
if data[item] == original_data[item]:
data.pop(item)
if attr := getattr(self, item, None): # this should never be None, just a safety default value
if not isinstance(attr, Attribute) or not attr.value_has_been_mutated:
data.pop(item)
continue
if isinstance(original_data[item], dict):
self._strip_unmodified_dict(data=data, original_data=original_data, variables=variables, item=item)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "infrahub-sdk"
version = "1.10.1"
version = "1.10.2"
description = "Python Client to interact with Infrahub"
authors = ["OpsMill <info@opsmill.com>"]
readme = "README.md"
Expand Down
19 changes: 19 additions & 0 deletions tests/integration/test_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ async def test_node_create_with_relationships(
assert node_after.name.value == node.name.value
assert node_after.manufacturer.peer.id == manufacturer_mercedes.id

async def test_node_update_with_original_data(
self,
default_branch: str,
client: InfrahubClient,
initial_schema: None,
):
person_marina = await client.create(kind="TestingPerson", name="marina", age=20)
await person_marina.save()

person_marina = await client.get(kind="TestingPerson", id=person_marina.id)

person_marina.age.value = 30
await person_marina.save()

person_marina.age.value = 20
await person_marina.save()
node = await client.get(kind="TestingPerson", id=person_marina.id)
assert node.age.value == 20, node.age.value

# async def test_node_update_payload_with_relationships(
# self,
# db: InfrahubDatabase,
Expand Down