Skip to content

Commit fde1504

Browse files
authored
Merge pull request #700 from opsmill/pog-query-metadata-IHS-172
Add ability to query for node metadata
2 parents d74e043 + 077bcc2 commit fde1504

File tree

10 files changed

+655
-17
lines changed

10 files changed

+655
-17
lines changed

changelog/+d3b5369f.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add ability to query for metadata on nodes to include information such as creation and update timestamps, creator and last user to update an object.

infrahub_sdk/client.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ async def get(
401401
fragment: bool = ...,
402402
prefetch_relationships: bool = ...,
403403
property: bool = ...,
404+
include_metadata: bool = ...,
404405
**kwargs: Any,
405406
) -> SchemaType | None: ...
406407

@@ -420,6 +421,7 @@ async def get(
420421
fragment: bool = ...,
421422
prefetch_relationships: bool = ...,
422423
property: bool = ...,
424+
include_metadata: bool = ...,
423425
**kwargs: Any,
424426
) -> SchemaType: ...
425427

@@ -439,6 +441,7 @@ async def get(
439441
fragment: bool = ...,
440442
prefetch_relationships: bool = ...,
441443
property: bool = ...,
444+
include_metadata: bool = ...,
442445
**kwargs: Any,
443446
) -> SchemaType: ...
444447

@@ -458,6 +461,7 @@ async def get(
458461
fragment: bool = ...,
459462
prefetch_relationships: bool = ...,
460463
property: bool = ...,
464+
include_metadata: bool = ...,
461465
**kwargs: Any,
462466
) -> InfrahubNode | None: ...
463467

@@ -477,6 +481,7 @@ async def get(
477481
fragment: bool = ...,
478482
prefetch_relationships: bool = ...,
479483
property: bool = ...,
484+
include_metadata: bool = ...,
480485
**kwargs: Any,
481486
) -> InfrahubNode: ...
482487

@@ -496,6 +501,7 @@ async def get(
496501
fragment: bool = ...,
497502
prefetch_relationships: bool = ...,
498503
property: bool = ...,
504+
include_metadata: bool = ...,
499505
**kwargs: Any,
500506
) -> InfrahubNode: ...
501507

@@ -514,6 +520,7 @@ async def get(
514520
fragment: bool = False,
515521
prefetch_relationships: bool = False,
516522
property: bool = False,
523+
include_metadata: bool = False,
517524
**kwargs: Any,
518525
) -> InfrahubNode | SchemaType | None:
519526
branch = branch or self.default_branch
@@ -547,6 +554,7 @@ async def get(
547554
fragment=fragment,
548555
prefetch_relationships=prefetch_relationships,
549556
property=property,
557+
include_metadata=include_metadata,
550558
**filters,
551559
)
552560

@@ -650,6 +658,7 @@ async def all(
650658
property: bool = ...,
651659
parallel: bool = ...,
652660
order: Order | None = ...,
661+
include_metadata: bool = ...,
653662
) -> list[SchemaType]: ...
654663

655664
@overload
@@ -669,6 +678,7 @@ async def all(
669678
property: bool = ...,
670679
parallel: bool = ...,
671680
order: Order | None = ...,
681+
include_metadata: bool = ...,
672682
) -> list[InfrahubNode]: ...
673683

674684
async def all(
@@ -687,6 +697,7 @@ async def all(
687697
property: bool = False,
688698
parallel: bool = False,
689699
order: Order | None = None,
700+
include_metadata: bool = False,
690701
) -> list[InfrahubNode] | list[SchemaType]:
691702
"""Retrieve all nodes of a given kind
692703
@@ -704,6 +715,7 @@ async def all(
704715
prefetch_relationships (bool, optional): Flag to indicate whether to prefetch related node data.
705716
parallel (bool, optional): Whether to use parallel processing for the query.
706717
order (Order, optional): Ordering related options. Setting `disable=True` enhances performances.
718+
include_metadata (bool, optional): If True, includes node_metadata and relationship_metadata in the query.
707719
708720
Returns:
709721
list[InfrahubNode]: List of Nodes
@@ -723,6 +735,7 @@ async def all(
723735
property=property,
724736
parallel=parallel,
725737
order=order,
738+
include_metadata=include_metadata,
726739
)
727740

728741
@overload
@@ -743,6 +756,7 @@ async def filters(
743756
property: bool = ...,
744757
parallel: bool = ...,
745758
order: Order | None = ...,
759+
include_metadata: bool = ...,
746760
**kwargs: Any,
747761
) -> list[SchemaType]: ...
748762

@@ -764,6 +778,7 @@ async def filters(
764778
property: bool = ...,
765779
parallel: bool = ...,
766780
order: Order | None = ...,
781+
include_metadata: bool = ...,
767782
**kwargs: Any,
768783
) -> list[InfrahubNode]: ...
769784

@@ -784,6 +799,7 @@ async def filters(
784799
property: bool = False,
785800
parallel: bool = False,
786801
order: Order | None = None,
802+
include_metadata: bool = False,
787803
**kwargs: Any,
788804
) -> list[InfrahubNode] | list[SchemaType]:
789805
"""Retrieve nodes of a given kind based on provided filters.
@@ -803,6 +819,7 @@ async def filters(
803819
partial_match (bool, optional): Allow partial match of filter criteria for the query.
804820
parallel (bool, optional): Whether to use parallel processing for the query.
805821
order (Order, optional): Ordering related options. Setting `disable=True` enhances performances.
822+
include_metadata (bool, optional): If True, includes node_metadata and relationship_metadata in the query.
806823
**kwargs (Any): Additional filter criteria for the query.
807824
808825
Returns:
@@ -829,6 +846,7 @@ async def process_page(page_offset: int, page_number: int) -> tuple[dict, Proces
829846
partial_match=partial_match,
830847
property=property,
831848
order=order,
849+
include_metadata=include_metadata,
832850
)
833851
query = Query(query=query_data)
834852
response = await self.execute_graphql(
@@ -1957,6 +1975,7 @@ def all(
19571975
property: bool = ...,
19581976
parallel: bool = ...,
19591977
order: Order | None = ...,
1978+
include_metadata: bool = ...,
19601979
) -> list[SchemaTypeSync]: ...
19611980

19621981
@overload
@@ -1976,6 +1995,7 @@ def all(
19761995
property: bool = ...,
19771996
parallel: bool = ...,
19781997
order: Order | None = ...,
1998+
include_metadata: bool = ...,
19791999
) -> list[InfrahubNodeSync]: ...
19802000

19812001
def all(
@@ -1994,6 +2014,7 @@ def all(
19942014
property: bool = False,
19952015
parallel: bool = False,
19962016
order: Order | None = None,
2017+
include_metadata: bool = False,
19972018
) -> list[InfrahubNodeSync] | list[SchemaTypeSync]:
19982019
"""Retrieve all nodes of a given kind
19992020
@@ -2011,6 +2032,7 @@ def all(
20112032
prefetch_relationships (bool, optional): Flag to indicate whether to prefetch related node data.
20122033
parallel (bool, optional): Whether to use parallel processing for the query.
20132034
order (Order, optional): Ordering related options. Setting `disable=True` enhances performances.
2035+
include_metadata (bool, optional): If True, includes node_metadata and relationship_metadata in the query.
20142036
20152037
Returns:
20162038
list[InfrahubNodeSync]: List of Nodes
@@ -2030,6 +2052,7 @@ def all(
20302052
property=property,
20312053
parallel=parallel,
20322054
order=order,
2055+
include_metadata=include_metadata,
20332056
)
20342057

20352058
def _process_nodes_and_relationships(
@@ -2091,6 +2114,7 @@ def filters(
20912114
property: bool = ...,
20922115
parallel: bool = ...,
20932116
order: Order | None = ...,
2117+
include_metadata: bool = ...,
20942118
**kwargs: Any,
20952119
) -> list[SchemaTypeSync]: ...
20962120

@@ -2112,6 +2136,7 @@ def filters(
21122136
property: bool = ...,
21132137
parallel: bool = ...,
21142138
order: Order | None = ...,
2139+
include_metadata: bool = ...,
21152140
**kwargs: Any,
21162141
) -> list[InfrahubNodeSync]: ...
21172142

@@ -2132,6 +2157,7 @@ def filters(
21322157
property: bool = False,
21332158
parallel: bool = False,
21342159
order: Order | None = None,
2160+
include_metadata: bool = False,
21352161
**kwargs: Any,
21362162
) -> list[InfrahubNodeSync] | list[SchemaTypeSync]:
21372163
"""Retrieve nodes of a given kind based on provided filters.
@@ -2151,6 +2177,7 @@ def filters(
21512177
partial_match (bool, optional): Allow partial match of filter criteria for the query.
21522178
parallel (bool, optional): Whether to use parallel processing for the query.
21532179
order (Order, optional): Ordering related options. Setting `disable=True` enhances performances.
2180+
include_metadata (bool, optional): If True, includes node_metadata and relationship_metadata in the query.
21542181
**kwargs (Any): Additional filter criteria for the query.
21552182
21562183
Returns:
@@ -2177,6 +2204,7 @@ def process_page(page_offset: int, page_number: int) -> tuple[dict, ProcessRelat
21772204
partial_match=partial_match,
21782205
property=property,
21792206
order=order,
2207+
include_metadata=include_metadata,
21802208
)
21812209
query = Query(query=query_data)
21822210
response = self.execute_graphql(
@@ -2266,6 +2294,7 @@ def get(
22662294
fragment: bool = ...,
22672295
prefetch_relationships: bool = ...,
22682296
property: bool = ...,
2297+
include_metadata: bool = ...,
22692298
**kwargs: Any,
22702299
) -> SchemaTypeSync | None: ...
22712300

@@ -2285,6 +2314,7 @@ def get(
22852314
fragment: bool = ...,
22862315
prefetch_relationships: bool = ...,
22872316
property: bool = ...,
2317+
include_metadata: bool = ...,
22882318
**kwargs: Any,
22892319
) -> SchemaTypeSync: ...
22902320

@@ -2304,6 +2334,7 @@ def get(
23042334
fragment: bool = ...,
23052335
prefetch_relationships: bool = ...,
23062336
property: bool = ...,
2337+
include_metadata: bool = ...,
23072338
**kwargs: Any,
23082339
) -> SchemaTypeSync: ...
23092340

@@ -2323,6 +2354,7 @@ def get(
23232354
fragment: bool = ...,
23242355
prefetch_relationships: bool = ...,
23252356
property: bool = ...,
2357+
include_metadata: bool = ...,
23262358
**kwargs: Any,
23272359
) -> InfrahubNodeSync | None: ...
23282360

@@ -2342,6 +2374,7 @@ def get(
23422374
fragment: bool = ...,
23432375
prefetch_relationships: bool = ...,
23442376
property: bool = ...,
2377+
include_metadata: bool = ...,
23452378
**kwargs: Any,
23462379
) -> InfrahubNodeSync: ...
23472380

@@ -2361,6 +2394,7 @@ def get(
23612394
fragment: bool = ...,
23622395
prefetch_relationships: bool = ...,
23632396
property: bool = ...,
2397+
include_metadata: bool = ...,
23642398
**kwargs: Any,
23652399
) -> InfrahubNodeSync: ...
23662400

@@ -2379,6 +2413,7 @@ def get(
23792413
fragment: bool = False,
23802414
prefetch_relationships: bool = False,
23812415
property: bool = False,
2416+
include_metadata: bool = False,
23822417
**kwargs: Any,
23832418
) -> InfrahubNodeSync | SchemaTypeSync | None:
23842419
branch = branch or self.default_branch
@@ -2412,6 +2447,7 @@ def get(
24122447
fragment=fragment,
24132448
prefetch_relationships=prefetch_relationships,
24142449
property=property,
2450+
include_metadata=include_metadata,
24152451
**filters,
24162452
)
24172453

infrahub_sdk/node/attribute.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from ..protocols_base import CoreNodeBase
88
from ..uuidt import UUIDT
9-
from .constants import IP_TYPES, PROPERTIES_FLAG, PROPERTIES_OBJECT, SAFE_VALUE
9+
from .constants import ATTRIBUTE_METADATA_OBJECT, IP_TYPES, PROPERTIES_FLAG, PROPERTIES_OBJECT, SAFE_VALUE
1010
from .property import NodeProperty
1111

1212
if TYPE_CHECKING:
@@ -57,11 +57,16 @@ def __init__(self, name: str, schema: AttributeSchemaAPI, data: Any | dict) -> N
5757

5858
self.source: NodeProperty | None = None
5959
self.owner: NodeProperty | None = None
60+
self.updated_by: NodeProperty | None = None
6061

6162
for prop_name in self._properties_object:
6263
if data.get(prop_name):
6364
setattr(self, prop_name, NodeProperty(data=data.get(prop_name))) # type: ignore[arg-type]
6465

66+
for prop_name in ATTRIBUTE_METADATA_OBJECT:
67+
if data.get(prop_name):
68+
setattr(self, prop_name, NodeProperty(data=data.get(prop_name))) # type: ignore[arg-type]
69+
6570
@property
6671
def value(self) -> Any:
6772
return self._value
@@ -104,7 +109,7 @@ def _generate_input_data(self) -> dict | None:
104109

105110
return {"data": data, "variables": variables}
106111

107-
def _generate_query_data(self, property: bool = False) -> dict | None:
112+
def _generate_query_data(self, property: bool = False, include_metadata: bool = False) -> dict | None:
108113
data: dict[str, Any] = {"value": None}
109114

110115
if property:
@@ -115,6 +120,11 @@ def _generate_query_data(self, property: bool = False) -> dict | None:
115120
for prop_name in self._properties_object:
116121
data[prop_name] = {"id": None, "display_label": None, "__typename": None}
117122

123+
if include_metadata:
124+
data["updated_at"] = None
125+
for prop_name in ATTRIBUTE_METADATA_OBJECT:
126+
data[prop_name] = {"id": None, "display_label": None, "__typename": None}
127+
118128
return data
119129

120130
def _generate_mutation_query(self) -> dict[str, Any]:

infrahub_sdk/node/constants.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33

44
PROPERTIES_FLAG = ["is_protected", "updated_at"]
55
PROPERTIES_OBJECT = ["source", "owner"]
6+
7+
# Attribute-level metadata object fields (in addition to PROPERTIES_OBJECT)
8+
ATTRIBUTE_METADATA_OBJECT = ["updated_by"]
9+
10+
# Node metadata fields (for node_metadata in GraphQL response)
11+
NODE_METADATA_FIELDS_FLAG = ["created_at", "updated_at"]
12+
NODE_METADATA_FIELDS_OBJECT = ["created_by", "updated_by"]
13+
14+
# Relationship metadata fields (for relationship_metadata in GraphQL response)
15+
RELATIONSHIP_METADATA_FIELDS_FLAG = ["updated_at"]
16+
RELATIONSHIP_METADATA_FIELDS_OBJECT = ["updated_by"]
617
SAFE_VALUE = re.compile(r"(^[\. /:a-zA-Z0-9_-]+$)|(^$)")
718

819
IP_TYPES = ipaddress.IPv4Interface | ipaddress.IPv6Interface | ipaddress.IPv4Network | ipaddress.IPv6Network

0 commit comments

Comments
 (0)