Skip to content
2 changes: 2 additions & 0 deletions changelog/529.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add `create_diff` method to create a diff summary between two timestamps
Update `get_diff_summary` to accept optional time range parameters
78 changes: 76 additions & 2 deletions infrahub_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import logging
import time
from collections.abc import Coroutine, MutableMapping
from datetime import datetime
from functools import wraps
from time import sleep
from typing import (
Expand All @@ -24,6 +25,7 @@

from .batch import InfrahubBatch, InfrahubBatchSync
from .branch import (
MUTATION_QUERY_TASK,
BranchData,
InfrahubBranchManager,
InfrahubBranchManagerSync,
Expand Down Expand Up @@ -1149,21 +1151,57 @@ async def query_gql_query(

return decode_json(response=resp)

async def create_diff(
self, branch: str, name: str, from_time: datetime, to_time: datetime, wait_until_completion: bool = True
) -> bool | str:
if from_time > to_time:
raise ValueError("from_time must be <= to_time")
input_data = {
"wait_until_completion": wait_until_completion,
"data": {
"name": name,
"branch": branch,
"from_time": from_time.isoformat(),
"to_time": to_time.isoformat(),
},
}

mutation_query = MUTATION_QUERY_TASK if not wait_until_completion else {"ok": None}
query = Mutation(mutation="DiffUpdate", input_data=input_data, query=mutation_query)
response = await self.execute_graphql(query=query.render(), tracker="mutation-diff-update")

if not wait_until_completion and "task" in response["DiffUpdate"]:
return response["DiffUpdate"]["task"]["id"]

return response["DiffUpdate"]["ok"]

async def get_diff_summary(
self,
branch: str,
name: str | None = None,
from_time: datetime | None = None,
to_time: datetime | None = None,
timeout: int | None = None,
tracker: str | None = None,
raise_for_error: bool = True,
) -> list[NodeDiff]:
query = get_diff_summary_query()
input_data = {"branch_name": branch}
if name:
input_data["name"] = name
if from_time and to_time and from_time > to_time:
raise ValueError("from_time must be <= to_time")
if from_time:
input_data["from_time"] = from_time.isoformat()
if to_time:
input_data["to_time"] = to_time.isoformat()
response = await self.execute_graphql(
query=query,
branch_name=branch,
timeout=timeout,
tracker=tracker,
raise_for_error=raise_for_error,
variables={"branch_name": branch},
variables=input_data,
)

node_diffs: list[NodeDiff] = []
Expand Down Expand Up @@ -2286,21 +2324,57 @@ def query_gql_query(

return decode_json(response=resp)

def create_diff(
self, branch: str, name: str, from_time: datetime, to_time: datetime, wait_until_completion: bool = True
) -> bool | str:
if from_time > to_time:
raise ValueError("from_time must be <= to_time")
input_data = {
"wait_until_completion": wait_until_completion,
"data": {
"name": name,
"branch": branch,
"from_time": from_time.isoformat(),
"to_time": to_time.isoformat(),
},
}

mutation_query = MUTATION_QUERY_TASK if not wait_until_completion else {"ok": None}
query = Mutation(mutation="DiffUpdate", input_data=input_data, query=mutation_query)
response = self.execute_graphql(query=query.render(), tracker="mutation-diff-update")

if not wait_until_completion and "task" in response["DiffUpdate"]:
return response["DiffUpdate"]["task"]["id"]

return response["DiffUpdate"]["ok"]

def get_diff_summary(
self,
branch: str,
name: str | None = None,
from_time: datetime | None = None,
to_time: datetime | None = None,
timeout: int | None = None,
tracker: str | None = None,
raise_for_error: bool = True,
) -> list[NodeDiff]:
query = get_diff_summary_query()
input_data = {"branch_name": branch}
if name:
input_data["name"] = name
if from_time and to_time and from_time > to_time:
raise ValueError("from_time must be <= to_time")
if from_time:
input_data["from_time"] = from_time.isoformat()
if to_time:
input_data["to_time"] = to_time.isoformat()
response = self.execute_graphql(
query=query,
branch_name=branch,
timeout=timeout,
tracker=tracker,
raise_for_error=raise_for_error,
variables={"branch_name": branch},
variables=input_data,
)

node_diffs: list[NodeDiff] = []
Expand Down
6 changes: 3 additions & 3 deletions infrahub_sdk/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ class NodeDiffPeer(TypedDict):

def get_diff_summary_query() -> str:
return """
query GetDiffTree($branch_name: String!) {
DiffTree(branch: $branch_name) {
query GetDiffTree($branch_name: String!, $name: String, $from_time: DateTime, $to_time: DateTime) {
DiffTree(branch: $branch_name, name: $name, from_time: $from_time, to_time: $to_time) {
nodes {
uuid
kind
Expand Down Expand Up @@ -121,7 +121,7 @@ def diff_tree_node_to_node_diff(node_dict: dict[str, Any], branch_name: str) ->
branch=branch_name,
kind=str(node_dict.get("kind")),
id=str(node_dict.get("uuid")),
action=str(node_dict.get("action")),
action=str(node_dict.get("status")),
display_label=str(node_dict.get("label")),
elements=element_diffs,
)
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/sdk/test_diff_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ async def test_diffsummary(clients: BothClients, mock_diff_tree_query, client_ty
"branch": "branch2",
"kind": "TestCar",
"id": "17fbadf0-6637-4fa2-43e6-1677ea170e0f",
"action": "None",
"action": "UPDATED",
"display_label": "nolt #444444",
"elements": [
{
Expand All @@ -124,7 +124,7 @@ async def test_diffsummary(clients: BothClients, mock_diff_tree_query, client_ty
"branch": "branch2",
"kind": "TestPerson",
"id": "17fbadf0-634f-05a8-43e4-1677e744d4c0",
"action": "None",
"action": "UPDATED",
"display_label": "Jane",
"elements": [
{
Expand All @@ -140,7 +140,7 @@ async def test_diffsummary(clients: BothClients, mock_diff_tree_query, client_ty
"branch": "branch2",
"kind": "TestPerson",
"id": "17fbadf0-6243-5d3c-43ee-167718ff8dac",
"action": "None",
"action": "UPDATED",
"display_label": "Jonathan",
"elements": [
{
Expand Down