Skip to content

Process all relationships and sub nodes within a GraphQL query #377

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: stable
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions changelog/+add-full-tree-to-store-process-nodes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
When processing relationships to add to the store, traverse tree and add all nodes to the store.
83 changes: 74 additions & 9 deletions infrahub_sdk/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -1521,6 +1521,34 @@
)
await self._process_mutation_result(mutation_name=mutation_name, response=response, timeout=timeout)

async def _process_sub_relationships(
self, node_data: dict[str, Any], branch: str, related_nodes: list[InfrahubNode], timeout: int | None = None
) -> None:
"""Recursively processes the Relationships of a InfrahubNode and add Related Nodes to a list.

Args:
node_data (dict[str, Any]): The item from the GraphQL response corresponding to the node.
branch (str): The branch name.
related_nodes (list[InfrahubNode]): The list to which related nodes will be appended.
timeout (int, optional): Overrides default timeout used when querying the graphql API. Specified in seconds.
"""

sub_relationships = {
node: info["node"]
for node, info in node_data["node"].items()
if isinstance(info, dict) and info.get("node", {}).get("__typename")
}
for rel_name in sub_relationships:
relation = node_data["node"].get(rel_name, None)

Check warning on line 1542 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L1542

Added line #L1542 was not covered by tests
if relation and relation.get("node", None):
related_node = await InfrahubNode.from_graphql(

Check warning on line 1544 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L1544

Added line #L1544 was not covered by tests
client=self._client, branch=branch, data=relation, timeout=timeout
)
related_nodes.append(related_node)
await self._process_sub_relationships(

Check warning on line 1548 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L1547-L1548

Added lines #L1547 - L1548 were not covered by tests
node_data=relation, branch=branch, related_nodes=related_nodes, timeout=timeout
)

async def _process_relationships(
self, node_data: dict[str, Any], branch: str, related_nodes: list[InfrahubNode], timeout: int | None = None
) -> None:
Expand All @@ -1541,6 +1569,9 @@
client=self._client, branch=branch, data=relation, timeout=timeout
)
related_nodes.append(related_node)
await self._process_sub_relationships(

Check warning on line 1572 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L1572

Added line #L1572 was not covered by tests
node_data=relation, branch=branch, related_nodes=related_nodes, timeout=timeout
)
elif rel and isinstance(rel, RelationshipManager):
peers = node_data["node"].get(rel_name, None)
if peers and peers["edges"]:
Expand All @@ -1549,6 +1580,9 @@
client=self._client, branch=branch, data=peer, timeout=timeout
)
related_nodes.append(related_node)
await self._process_sub_relationships(

Check warning on line 1583 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L1583

Added line #L1583 was not covered by tests
node_data=peer, branch=branch, related_nodes=related_nodes, timeout=timeout
)

async def get_pool_allocated_resources(self, resource: InfrahubNode) -> list[InfrahubNode]:
"""Fetch all nodes that were allocated for the pool and a given resource.
Expand Down Expand Up @@ -2044,12 +2078,37 @@
)
self._process_mutation_result(mutation_name=mutation_name, response=response, timeout=timeout)

def _process_sub_relationships(
self, node_data: dict[str, Any], branch: str, related_nodes: list[InfrahubNodeSync], timeout: int | None = None
) -> None:
"""Recursively processes the Relationships of a InfrahubNodeSync and add Related Nodes to a list.

Args:
node_data (dict[str, Any]): The item from the GraphQL response corresponding to the node.
branch (str): The branch name.
related_nodes (list[InfrahubNode]): The list to which related nodes will be appended.
timeout (int, optional): Overrides default timeout used when querying the graphql API. Specified in seconds.

"""

sub_relationships = {
node: info["node"]
for node, info in node_data["node"].items()
if isinstance(info, dict) and info.get("node", {}).get("__typename")
}
for rel_name in sub_relationships:
relation = node_data["node"].get(rel_name, None)

Check warning on line 2100 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L2100

Added line #L2100 was not covered by tests
if relation and relation.get("node", None):
related_node = InfrahubNodeSync.from_graphql(

Check warning on line 2102 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L2102

Added line #L2102 was not covered by tests
client=self._client, branch=branch, data=relation, timeout=timeout
)
related_nodes.append(related_node)
self._process_sub_relationships(

Check warning on line 2106 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L2105-L2106

Added lines #L2105 - L2106 were not covered by tests
node_data=relation, branch=branch, related_nodes=related_nodes, timeout=timeout
)

def _process_relationships(
self,
node_data: dict[str, Any],
branch: str,
related_nodes: list[InfrahubNodeSync],
timeout: int | None = None,
self, node_data: dict[str, Any], branch: str, related_nodes: list[InfrahubNodeSync], timeout: int | None = None
) -> None:
"""Processes the Relationships of a InfrahubNodeSync and add Related Nodes to a list.

Expand All @@ -2063,20 +2122,26 @@
for rel_name in self._relationships:
rel = getattr(self, rel_name)
if rel and isinstance(rel, RelatedNodeSync):
relation = node_data["node"].get(rel_name)
if relation.get("node", None):
relation = node_data["node"].get(rel_name, None)

Check warning on line 2125 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L2125

Added line #L2125 was not covered by tests
if relation and relation.get("node", None):
related_node = InfrahubNodeSync.from_graphql(
client=self._client, branch=branch, data=relation, timeout=timeout
)
related_nodes.append(related_node)
self._process_sub_relationships(

Check warning on line 2131 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L2131

Added line #L2131 was not covered by tests
node_data=relation, branch=branch, related_nodes=related_nodes, timeout=timeout
)
elif rel and isinstance(rel, RelationshipManagerSync):
peers = node_data["node"].get(rel_name)
if peers:
peers = node_data["node"].get(rel_name, None)

Check warning on line 2135 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L2135

Added line #L2135 was not covered by tests
if peers and peers["edges"]:
for peer in peers["edges"]:
related_node = InfrahubNodeSync.from_graphql(
client=self._client, branch=branch, data=peer, timeout=timeout
)
related_nodes.append(related_node)
self._process_sub_relationships(

Check warning on line 2142 in infrahub_sdk/node.py

View check run for this annotation

Codecov / codecov/patch

infrahub_sdk/node.py#L2142

Added line #L2142 was not covered by tests
node_data=peer, branch=branch, related_nodes=related_nodes, timeout=timeout
)

def get_pool_allocated_resources(self, resource: InfrahubNodeSync) -> list[InfrahubNodeSync]:
"""Fetch all nodes that were allocated for the pool and a given resource.
Expand Down
Loading