Skip to content

Commit a56a48e

Browse files
authored
Merge pull request #315 from opsmill/develop
Release 1.9.0
2 parents 5bedc52 + aef9515 commit a56a48e

File tree

10 files changed

+183
-112
lines changed

10 files changed

+183
-112
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,20 @@ This project uses [*towncrier*](https://towncrier.readthedocs.io/) and the chang
1111

1212
<!-- towncrier release notes start -->
1313

14+
## [1.9.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.9.0) - 2025-03-21
15+
16+
### Added
17+
18+
- Add 'schema_hash' parameter to client.schema.all to only optionally refresh the schema if the provided hash differs from what the client has already cached. ([#152](https://github.com/opsmill/infrahub-sdk-python/issues/152))
19+
20+
### Changed
21+
22+
- CoreStandardGroups created or updated by a generator in Infrahub are now stored as a member of the CoreGeneratorGroup. Previously they were being stored as children of the CoreGeneratorGroup.
23+
24+
### Fixed
25+
26+
- The SDK client query methods (get, filters, all) default behaviour has changed. The query methods will store the retrieved nodes in the internal store by default, where previously this behaviour had to be enabled explicitly using the `populate_store` argument. ([#15](https://github.com/opsmill/infrahub-sdk-python/issues/15))
27+
1428
## [1.8.0](https://github.com/opsmill/infrahub-sdk-python/tree/v1.8.0) - 2025-03-19
1529

1630
### Deprecated

docs/docs/python-sdk/guides/store.mdx

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,39 @@ The store can also be used to store Nodes that we retrieve using the client quer
1414

1515
## Storing nodes in the store
1616

17-
Nodes retrieved from Infrahub using a query method, will be stored in the internal store when you set the `populate_store` argument to `True`.
18-
Nodes stored in the store using this method can be retrieved using their `id` as the key in the store.
17+
Nodes retrieved from Infrahub using a the SDK client's query methods, such as the `get` `filters` or `all` method, will be automatically stored in the internal store. Nodes stored in the store using this method can be retrieved using their `id` as the key in the store.
1918

2019
<Tabs groupId="async-sync">
2120
<TabItem value="Async" default>
2221

2322
```python
24-
tag = await client.get(kind="BuiltinTag", name__value="RED", populate_store=True)
23+
tag = await client.get(kind="BuiltinTag", name__value="RED")
24+
```
25+
26+
</TabItem>
27+
<TabItem value="Sync" default>
28+
29+
```python
30+
tag = client.get(kind="BuiltinTag", name__value="RED")
31+
```
32+
33+
</TabItem>
34+
</Tabs>
35+
36+
This behaviour may not be desirable in all scenarios, therefor you can explicitly disable this behaviour by setting the `populate_store` argument to `False` when calling the query methods.
37+
38+
<Tabs groupId="async-sync">
39+
<TabItem value="Async" default>
40+
41+
```python
42+
tag = await client.get(kind="BuiltinTag", name__value="RED", populate_store=False)
2543
```
2644

2745
</TabItem>
2846
<TabItem value="Sync" default>
2947

3048
```python
31-
tag = client.get(kind="BuiltinTag", name__value="RED", populate_store=True)
49+
tag = client.get(kind="BuiltinTag", name__value="RED", populate_store=False)
3250
```
3351

3452
</TabItem>
@@ -42,15 +60,15 @@ You can store nodes in the object store manually using the `set` method. This ha
4260
<TabItem value="Async" default>
4361

4462
```python
45-
tag = await client.get(kind="BuiltinTag", name__value="RED")
63+
tag = await client.get(kind="BuiltinTag", name__value="RED", populate_store=False)
4664
client.store.set(key=tag.name.value, node=tag)
4765
```
4866

4967
</TabItem>
5068
<TabItem value="Sync" default>
5169

5270
```python
53-
tag = client.get(kind="BuiltinTag", name__value="RED")
71+
tag = client.get(kind="BuiltinTag", name__value="RED", populate_store=False)
5472
client.store.set(key=tag.name.value, node=tag)
5573
```
5674

@@ -60,13 +78,13 @@ You can store nodes in the object store manually using the `set` method. This ha
6078
## Retrieving object from the store
6179

6280
Nodes can be retrieved from the internal store using the key that was used to store them.
63-
For nodes that are stored using the `populate_store` argument on a query method, this will be their `id`.
81+
For nodes that are stored by the client's query methods, this will be their `id`.
6482

6583
<Tabs groupId="async-sync">
6684
<TabItem value="Async" default>
6785

6886
```python
69-
tag = await client.get(kind="BuiltinTag", name__value="RED", populate_store=True)
87+
tag = await client.get(kind="BuiltinTag", name__value="RED")
7088
tag_in_store = client.store.get(key=tag.id)
7189
assert tag == tag_in_store
7290
```
@@ -75,7 +93,7 @@ For nodes that are stored using the `populate_store` argument on a query method,
7593
<TabItem value="Sync" default>
7694

7795
```python
78-
tag = client.get(kind="BuiltinTag", name__value="RED", populate_store=True)
96+
tag = client.get(kind="BuiltinTag", name__value="RED")
7997
tag_in_store = client.store.get(key=tag.id)
8098
assert tag == tag_in_store
8199
```
@@ -89,7 +107,7 @@ For nodes that have been added manually to the store, this will be the key that
89107
<TabItem value="Async" default>
90108

91109
```python
92-
tag = await client.get(kind="BuiltinTag", name__value="RED")
110+
tag = await client.get(kind="BuiltinTag", name__value="RED", populate_store=False)
93111
client.store.set(key=tag.name.value, node=tag)
94112
tag_in_store = client.store.get(key=tag.name.value)
95113
assert tag == tag_in_store
@@ -99,7 +117,7 @@ For nodes that have been added manually to the store, this will be the key that
99117
<TabItem value="Sync" default>
100118

101119
```python
102-
tag = client.get(kind="BuiltinTag", name__value="RED")
120+
tag = client.get(kind="BuiltinTag", name__value="RED", populate_store=False)
103121
client.store.set(key=tag.name.value, node=tag)
104122
tag_in_store = client.store.get(key=tag.name.value)
105123
assert tag == tag_in_store
@@ -142,7 +160,7 @@ You can use a custom store, outside of the Infrahub SDK client. Storing or retri
142160
from infrahub_sdk.store import NodeStore
143161
store = NodeStore()
144162

145-
device = await client.get(kind="TestDevice", name__value="atl1-edge1")
163+
device = await client.get(kind="TestDevice", name__value="atl1-edge1", populate_store=False)
146164
store.set(key=device.name.value, node=device)
147165
store.get(key=device.name.value)
148166
```
@@ -154,7 +172,7 @@ You can use a custom store, outside of the Infrahub SDK client. Storing or retri
154172
from infrahub_sdk.store import NodeStoreSync
155173
store = NodeStoreSync()
156174

157-
device = await client.get(kind="TestDevice", name__value="atl1-edge1")
175+
device = await client.get(kind="TestDevice", name__value="atl1-edge1", populate_store=False)
158176
store.set(key=device.name.value, node=device)
159177
store.get(key=device.name.value)
160178
```

infrahub_sdk/client.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ async def get(
470470
hfid: list[str] | None = None,
471471
include: list[str] | None = None,
472472
exclude: list[str] | None = None,
473-
populate_store: bool = False,
473+
populate_store: bool = True,
474474
fragment: bool = False,
475475
prefetch_relationships: bool = False,
476476
property: bool = False,
@@ -624,7 +624,7 @@ async def all(
624624
at: Timestamp | None = None,
625625
branch: str | None = None,
626626
timeout: int | None = None,
627-
populate_store: bool = False,
627+
populate_store: bool = True,
628628
offset: int | None = None,
629629
limit: int | None = None,
630630
include: list[str] | None = None,
@@ -720,7 +720,7 @@ async def filters(
720720
at: Timestamp | None = None,
721721
branch: str | None = None,
722722
timeout: int | None = None,
723-
populate_store: bool = False,
723+
populate_store: bool = True,
724724
offset: int | None = None,
725725
limit: int | None = None,
726726
include: list[str] | None = None,
@@ -1745,7 +1745,7 @@ def all(
17451745
at: Timestamp | None = None,
17461746
branch: str | None = None,
17471747
timeout: int | None = None,
1748-
populate_store: bool = False,
1748+
populate_store: bool = True,
17491749
offset: int | None = None,
17501750
limit: int | None = None,
17511751
include: list[str] | None = None,
@@ -1876,7 +1876,7 @@ def filters(
18761876
at: Timestamp | None = None,
18771877
branch: str | None = None,
18781878
timeout: int | None = None,
1879-
populate_store: bool = False,
1879+
populate_store: bool = True,
18801880
offset: int | None = None,
18811881
limit: int | None = None,
18821882
include: list[str] | None = None,
@@ -2129,7 +2129,7 @@ def get(
21292129
hfid: list[str] | None = None,
21302130
include: list[str] | None = None,
21312131
exclude: list[str] | None = None,
2132-
populate_store: bool = False,
2132+
populate_store: bool = True,
21332133
fragment: bool = False,
21342134
prefetch_relationships: bool = False,
21352135
property: bool = False,

infrahub_sdk/query_groups.py

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ def __init__(self) -> None:
1919
self.related_node_ids: list[str] = []
2020
self.related_group_ids: list[str] = []
2121
self.unused_member_ids: list[str] | None = None
22-
self.unused_child_ids: list[str] | None = None
2322
self.previous_members: list[RelatedNodeBase] | None = None
2423
self.previous_children: list[RelatedNodeBase] | None = None
2524
self.identifier: str | None = None
@@ -88,15 +87,14 @@ def __init__(self, client: InfrahubClient) -> None:
8887
async def get_group(self, store_peers: bool = False) -> InfrahubNode | None:
8988
group_name = self._generate_group_name()
9089
try:
91-
group = await self.client.get(kind=self.group_type, name__value=group_name, include=["members", "children"])
90+
group = await self.client.get(kind=self.group_type, name__value=group_name, include=["members"])
9291
except NodeNotFoundError:
9392
return None
9493

9594
if not store_peers:
9695
return group
9796

9897
self.previous_members = group.members.peers # type: ignore[attr-defined]
99-
self.previous_children = group.children.peers # type: ignore[attr-defined]
10098
return group
10199

102100
async def delete_unused(self) -> None:
@@ -105,11 +103,6 @@ async def delete_unused(self) -> None:
105103
if member.id in self.unused_member_ids and member.typename:
106104
await self.client.delete(kind=member.typename, id=member.id)
107105

108-
if self.previous_children and self.unused_child_ids:
109-
for child in self.previous_children:
110-
if child.id in self.unused_child_ids and child.typename:
111-
await self.client.delete(kind=child.typename, id=child.id)
112-
113106
async def add_related_nodes(self, ids: list[str], update_group_context: bool | None = None) -> None:
114107
"""
115108
Add related Nodes IDs to the context.
@@ -140,15 +133,9 @@ async def update_group(self) -> None:
140133
"""
141134
Create or update (using upsert) a CoreStandardGroup to store all the Nodes and Groups used during an execution.
142135
"""
143-
children: list[str] = []
144-
members: list[str] = []
145-
146-
if self.related_group_ids:
147-
children = self.related_group_ids
148-
if self.related_node_ids:
149-
members = self.related_node_ids
136+
members: list[str] = self.related_group_ids + self.related_node_ids
150137

151-
if not children and not members:
138+
if not members:
152139
return
153140

154141
group_name = self._generate_group_name()
@@ -164,7 +151,6 @@ async def update_group(self) -> None:
164151
name=group_name,
165152
description=description,
166153
members=members,
167-
children=children,
168154
)
169155
await group.save(allow_upsert=True, update_group_context=False)
170156

@@ -173,7 +159,6 @@ async def update_group(self) -> None:
173159

174160
# Calculate how many nodes should be deleted
175161
self.unused_member_ids = set(existing_group.members.peer_ids) - set(members) # type: ignore
176-
self.unused_child_ids = set(existing_group.children.peer_ids) - set(children) # type: ignore
177162

178163
if not self.delete_unused_nodes:
179164
return
@@ -194,15 +179,14 @@ def __init__(self, client: InfrahubClientSync) -> None:
194179
def get_group(self, store_peers: bool = False) -> InfrahubNodeSync | None:
195180
group_name = self._generate_group_name()
196181
try:
197-
group = self.client.get(kind=self.group_type, name__value=group_name, include=["members", "children"])
182+
group = self.client.get(kind=self.group_type, name__value=group_name, include=["members"])
198183
except NodeNotFoundError:
199184
return None
200185

201186
if not store_peers:
202187
return group
203188

204189
self.previous_members = group.members.peers # type: ignore[attr-defined]
205-
self.previous_children = group.children.peers # type: ignore[attr-defined]
206190
return group
207191

208192
def delete_unused(self) -> None:
@@ -211,11 +195,6 @@ def delete_unused(self) -> None:
211195
if member.id in self.unused_member_ids and member.typename:
212196
self.client.delete(kind=member.typename, id=member.id)
213197

214-
if self.previous_children and self.unused_child_ids:
215-
for child in self.previous_children:
216-
if child.id in self.unused_child_ids and child.typename:
217-
self.client.delete(kind=child.typename, id=child.id)
218-
219198
def add_related_nodes(self, ids: list[str], update_group_context: bool | None = None) -> None:
220199
"""
221200
Add related Nodes IDs to the context.
@@ -246,15 +225,9 @@ def update_group(self) -> None:
246225
"""
247226
Create or update (using upsert) a CoreStandardGroup to store all the Nodes and Groups used during an execution.
248227
"""
249-
children: list[str] = []
250-
members: list[str] = []
251-
252-
if self.related_group_ids:
253-
children = self.related_group_ids
254-
if self.related_node_ids:
255-
members = self.related_node_ids
228+
members: list[str] = self.related_node_ids + self.related_group_ids
256229

257-
if not children and not members:
230+
if not members:
258231
return
259232

260233
group_name = self._generate_group_name()
@@ -270,7 +243,6 @@ def update_group(self) -> None:
270243
name=group_name,
271244
description=description,
272245
members=members,
273-
children=children,
274246
)
275247
group.save(allow_upsert=True, update_group_context=False)
276248

@@ -279,7 +251,6 @@ def update_group(self) -> None:
279251

280252
# Calculate how many nodes should be deleted
281253
self.unused_member_ids = set(existing_group.members.peer_ids) - set(members) # type: ignore
282-
self.unused_child_ids = set(existing_group.children.peer_ids) - set(children) # type: ignore
283254

284255
if not self.delete_unused_nodes:
285256
return

0 commit comments

Comments
 (0)