Using the client store
The client in the SDK contains a store object that is used to store Nodes in a local cache.
The store is mainly used for the internal working of the SDK. It is used to create relations between nodes that might not yet exist in the database, or to store relations for nodes that were retrieved from the database, amongst other things.
The store can also be used to store Nodes that we retrieve using the client query methods. This allows to not have to keep references to nodes we retrieved throughout scripts, or avoids situations where we have to redo queries to retrieve nodes.
Storing nodes in the store
Nodes retrieved from Infrahub using a query method, will be stored in the internal store when you set the populate_store
argument to True
.
Nodes stored in the store using this method can be retrieved using their id
as the key in the store.
- Async
- Sync
tag = await client.get(kind="BuiltinTag", name__value="RED", populate_store=True)
tag = client.get(kind="BuiltinTag", name__value="RED", populate_store=True)
Manually storing objects in the store
You can store nodes in the object store manually using the set
method. This has the advantage that you can choose which key you use to reference the node in the store. For example, we could use the name attribute value of the node as the key.
- Async
- Sync
tag = await client.get(kind="BuiltinTag", name__value="RED")
client.store.set(key=tag.name.value, node=tag)
tag = client.get(kind="BuiltinTag", name__value="RED")
client.store.set(key=tag.name.value, node=tag)
Retrieving object from the store
Nodes can be retrieved from the internal store using the key that was used to store them.
For nodes that are stored using the populate_store
argument on a query method, this will be their id
.
- Async
- Sync
tag = await client.get(kind="BuiltinTag", name__value="RED", populate_store=True)
tag_in_store = client.store.get(key=tag.id)
assert tag == tag_in_store
tag = client.get(kind="BuiltinTag", name__value="RED", populate_store=True)
tag_in_store = client.store.get(key=tag.id)
assert tag == tag_in_store
For nodes that have been added manually to the store, this will be the key that you specified when storing the node. For example, when you used the name attribute value of the node you can use that name to retrieve the node from the store.
- Async
- Sync
tag = await client.get(kind="BuiltinTag", name__value="RED")
client.store.set(key=tag.name.value, node=tag)
tag_in_store = client.store.get(key=tag.name.value)
assert tag == tag_in_store
tag = client.get(kind="BuiltinTag", name__value="RED")
client.store.set(key=tag.name.value, node=tag)
tag_in_store = client.store.get(key=tag.name.value)
assert tag == tag_in_store
Prefetch relationships
When you are using the internal store, you can use the prefect_relationships
argument in all the client query methods. All the related nodes, for the relationships that are in scope of the query will be retrieved using this option. This has the advantage that you don't have to fetch
related node(s) for a relation manually, but it comes at the cost of a more complex query, which might have an impact on the performance of the query.
- Async
- Sync
device = await client.get(kind="TestDevice", name__value="atl1-edge1", populate_store=True, prefetch_relationships=True, include=["interfaces"])
print(device.interfaces.peers[0].peer.name.value)
device = client.get(kind="TestDevice", name__value="atl1-edge1", populate_store=True, prefetch_relationships=True, include=["interfaces"])
print(device.interfaces.peers[0].peer.name.value)
Using a custom store
You can use a custom store, outside of the Infrahub SDK client. Storing or retrieving nodes works exactly the same as for the internal store. The advantage is that you are in full control of the contents of the store.
- Async
- Sync
from infrahub_sdk.store import NodeStore
store = NodeStore()
device = await client.get(kind="TestDevice", name__value="atl1-edge1")
store.set(key=device.name.value, node=device)
store.get(key=device.name.value)
from infrahub_sdk.store import NodeStoreSync
store = NodeStoreSync()
device = await client.get(kind="TestDevice", name__value="atl1-edge1")
store.set(key=device.name.value, node=device)
store.get(key=device.name.value)