Skip to content

Commit 42c6855

Browse files
committed
Add support for convert_query_response to Python Transforms
1 parent ba4f0c9 commit 42c6855

File tree

28 files changed

+187
-11
lines changed

28 files changed

+187
-11
lines changed

backend/infrahub/api/transformation.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ async def transform_python(
8888
branch=branch_params.branch.name,
8989
transform_location=f"{transform.file_path.value}::{transform.class_name.value}",
9090
timeout=transform.timeout.value,
91+
convert_query_response=transform.convert_query_response.value or False,
9192
data=data,
9293
)
9394

backend/infrahub/artifacts/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ class CheckArtifactCreate(BaseModel):
1212
content_type: str = Field(..., description="Content type of the artifact")
1313
transform_type: str = Field(..., description="The type of transform associated with this artifact")
1414
transform_location: str = Field(..., description="The transforms location within the repository")
15+
convert_query_response: bool = Field(
16+
default=False,
17+
description="Indicate if the query response should be converted to InfrahubNode objects for Python transforms",
18+
)
1519
repository_id: str = Field(..., description="The unique ID of the Repository")
1620
repository_name: str = Field(..., description="The name of the Repository")
1721
repository_kind: str = Field(..., description="The kind of the Repository")

backend/infrahub/computed_attribute/tasks.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ async def process_transform(
113113
location=f"{transform.file_path.value}::{transform.class_name.value}",
114114
data=data,
115115
client=service.client,
116+
convert_query_response=transform.convert_query_response.value,
116117
) # type: ignore[misc]
117118

118119
await service.client.execute_graphql(

backend/infrahub/core/protocols.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ class CoreTransformJinja2(CoreTransformation):
478478
class CoreTransformPython(CoreTransformation):
479479
file_path: String
480480
class_name: String
481+
convert_query_response: BooleanOptional
481482

482483

483484
class CoreUserValidator(CoreValidator):

backend/infrahub/core/schema/definitions/core/transform.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,6 @@
9292
attributes=[
9393
Attr(name="file_path", kind="Text"),
9494
Attr(name="class_name", kind="Text"),
95+
Attr(name="convert_query_response", kind="Boolean", optional=True, default_value=False),
9596
],
9697
)

backend/infrahub/git/integrator.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import yaml
1111
from infrahub_sdk import InfrahubClient # noqa: TC002
1212
from infrahub_sdk.exceptions import ValidationError
13+
from infrahub_sdk.node import InfrahubNode
1314
from infrahub_sdk.protocols import (
1415
CoreArtifact,
1516
CoreArtifactDefinition,
@@ -53,7 +54,6 @@
5354
import types
5455

5556
from infrahub_sdk.checks import InfrahubCheck
56-
from infrahub_sdk.node import InfrahubNode
5757
from infrahub_sdk.schema.repository import InfrahubRepositoryArtifactDefinitionConfig
5858
from infrahub_sdk.transforms import InfrahubTransform
5959

@@ -123,6 +123,10 @@ class TransformPythonInformation(BaseModel):
123123
timeout: int
124124
"""Timeout for the function."""
125125

126+
convert_query_response: bool = Field(
127+
..., description="Indicate if the transform should convert the query response to InfrahubNode objects"
128+
)
129+
126130

127131
class InfrahubRepositoryIntegrator(InfrahubRepositoryBase):
128132
"""
@@ -874,6 +878,7 @@ async def get_python_transforms(
874878
file_path=file_path,
875879
query=str(graphql_query.id),
876880
timeout=transform_class.timeout,
881+
convert_query_response=transform.convert_query_response,
877882
)
878883
)
879884

@@ -1005,6 +1010,7 @@ async def create_python_transform(
10051010
"file_path": transform.file_path,
10061011
"class_name": transform.class_name,
10071012
"timeout": transform.timeout,
1013+
"convert_query_response": transform.convert_query_response,
10081014
}
10091015
create_payload = self.sdk.schema.generate_payload_create(
10101016
schema=schema,
@@ -1028,6 +1034,9 @@ async def update_python_transform(
10281034
if existing_transform.timeout.value != local_transform.timeout:
10291035
existing_transform.timeout.value = local_transform.timeout
10301036

1037+
if existing_transform.convert_query_response.value != local_transform.convert_query_response:
1038+
existing_transform.convert_query_response.value = local_transform.convert_query_response
1039+
10311040
await existing_transform.save()
10321041

10331042
@classmethod
@@ -1038,6 +1047,7 @@ async def compare_python_transform(
10381047
existing_transform.query.id != local_transform.query
10391048
or existing_transform.file_path.value != local_transform.file_path
10401049
or existing_transform.timeout.value != local_transform.timeout
1050+
or existing_transform.convert_query_response.value != local_transform.convert_query_response
10411051
):
10421052
return False
10431053
return True
@@ -1129,7 +1139,13 @@ async def execute_python_check(
11291139

11301140
@task(name="python-transform-execute", task_run_name="Execute Python Transform", cache_policy=NONE) # type: ignore[arg-type]
11311141
async def execute_python_transform(
1132-
self, branch_name: str, commit: str, location: str, client: InfrahubClient, data: dict | None = None
1142+
self,
1143+
branch_name: str,
1144+
commit: str,
1145+
location: str,
1146+
client: InfrahubClient,
1147+
convert_query_response: bool,
1148+
data: dict | None = None,
11331149
) -> Any:
11341150
"""Execute A Python Transform stored in the repository."""
11351151
log = get_run_logger()
@@ -1159,7 +1175,13 @@ async def execute_python_transform(
11591175

11601176
transform_class: type[InfrahubTransform] = getattr(module, class_name)
11611177

1162-
transform = transform_class(root_directory=commit_worktree.directory, branch=branch_name, client=client)
1178+
transform = transform_class(
1179+
root_directory=commit_worktree.directory,
1180+
branch=branch_name,
1181+
client=client,
1182+
convert_query_response=convert_query_response,
1183+
infrahub_node=InfrahubNode,
1184+
)
11631185
return await transform.run(data=data)
11641186

11651187
except ModuleNotFoundError as exc:
@@ -1216,6 +1238,7 @@ async def artifact_generate(
12161238
location=transformation_location,
12171239
data=response,
12181240
client=self.sdk,
1241+
convert_query_response=transformation.convert_query_response.value,
12191242
) # type: ignore[misc]
12201243

12211244
if definition.content_type.value == ContentType.APPLICATION_JSON.value and isinstance(artifact_content, dict):
@@ -1275,6 +1298,7 @@ async def render_artifact(
12751298
location=message.transform_location,
12761299
data=response,
12771300
client=self.sdk,
1301+
convert_query_response=message.convert_query_response,
12781302
) # type: ignore[misc]
12791303

12801304
if message.content_type == ContentType.APPLICATION_JSON.value and isinstance(artifact_content, dict):

backend/infrahub/git/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ class RequestArtifactGenerate(BaseModel):
2929
repository_name: str = Field(..., description="The name of the Repository")
3030
repository_kind: str = Field(..., description="The kind of the Repository")
3131
branch_name: str = Field(..., description="The branch where the check is run")
32+
convert_query_response: bool = Field(
33+
default=False,
34+
description="Indicate if the query response should be converted to InfrahubNode objects for Python transforms",
35+
)
3236
target_id: str = Field(..., description="The ID of the target object for this artifact")
3337
target_kind: str = Field(..., description="The kind of the target object for this artifact")
3438
target_name: str = Field(..., description="Name of the artifact target")

backend/infrahub/git/tasks.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,12 @@ async def generate_request_artifact_definition(
339339
)
340340
transform_location = ""
341341

342+
convert_query_response = False
342343
if transform.typename == InfrahubKind.TRANSFORMJINJA2:
343344
transform_location = transform.template_path.value
344345
elif transform.typename == InfrahubKind.TRANSFORMPYTHON:
345346
transform_location = f"{transform.file_path.value}::{transform.class_name.value}"
347+
convert_query_response = transform.convert_query_response.value
346348

347349
for relationship in group.members.peers:
348350
member = relationship.peer
@@ -368,6 +370,7 @@ async def generate_request_artifact_definition(
368370
target_name=member.display_label,
369371
target_kind=member.get_kind(),
370372
timeout=transform.timeout.value,
373+
convert_query_response=convert_query_response,
371374
context=context,
372375
)
373376

backend/infrahub/message_bus/operations/requests/proposed_change.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,9 @@ async def refresh_artifacts(message: messages.RequestProposedChangeRefreshArtifa
319319
file_path {
320320
value
321321
}
322+
convert_query_response {
323+
value
324+
}
322325
}
323326
repository {
324327
node {
@@ -526,6 +529,9 @@ def _parse_artifact_definitions(definitions: list[dict]) -> list[ProposedChangeA
526529
elif artifact_definition.transform_kind == InfrahubKind.TRANSFORMPYTHON:
527530
artifact_definition.class_name = definition["node"]["transformation"]["node"]["class_name"]["value"]
528531
artifact_definition.file_path = definition["node"]["transformation"]["node"]["file_path"]["value"]
532+
artifact_definition.convert_query_response = definition["node"]["transformation"]["node"][
533+
"convert_query_response"
534+
]["value"]
529535

530536
parsed.append(artifact_definition)
531537

backend/infrahub/message_bus/types.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ class ProposedChangeArtifactDefinition(BaseModel):
9696
class_name: str = Field(default="")
9797
content_type: str
9898
file_path: str = Field(default="")
99+
convert_query_response: bool = Field(
100+
default=False, description="Convert query response to InfrahubNode objects for Python based transforms"
101+
)
99102
timeout: int
100103

101104
@property

0 commit comments

Comments
 (0)