Skip to content

Commit b7ff042

Browse files
authored
Merge pull request #223 from opsmill/lgu-add-order-disable
Order of retrieved nodes can be disabled
2 parents 5f28683 + 9b1fe7a commit b7ff042

File tree

8 files changed

+72
-4
lines changed

8 files changed

+72
-4
lines changed

changelog/+nodes-order.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
`client.all` and `client.filters` now support `order` parameter allowing to disable order of retrieve nodes in order to enhance performances

infrahub_sdk/client.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
from .schema import InfrahubSchema, InfrahubSchemaSync, NodeSchemaAPI
5252
from .store import NodeStore, NodeStoreSync
5353
from .timestamp import Timestamp
54-
from .types import AsyncRequester, HTTPMethod, SyncRequester
54+
from .types import AsyncRequester, HTTPMethod, Order, SyncRequester
5555
from .utils import decode_json, get_user_permissions, is_valid_uuid
5656

5757
if TYPE_CHECKING:
@@ -576,6 +576,7 @@ async def all(
576576
prefetch_relationships: bool = ...,
577577
property: bool = ...,
578578
parallel: bool = ...,
579+
order: Order | None = ...,
579580
) -> list[SchemaType]: ...
580581

581582
@overload
@@ -594,6 +595,7 @@ async def all(
594595
prefetch_relationships: bool = ...,
595596
property: bool = ...,
596597
parallel: bool = ...,
598+
order: Order | None = ...,
597599
) -> list[InfrahubNode]: ...
598600

599601
async def all(
@@ -611,6 +613,7 @@ async def all(
611613
prefetch_relationships: bool = False,
612614
property: bool = False,
613615
parallel: bool = False,
616+
order: Order | None = None,
614617
) -> list[InfrahubNode] | list[SchemaType]:
615618
"""Retrieve all nodes of a given kind
616619
@@ -627,6 +630,7 @@ async def all(
627630
fragment (bool, optional): Flag to use GraphQL fragments for generic schemas.
628631
prefetch_relationships (bool, optional): Flag to indicate whether to prefetch related node data.
629632
parallel (bool, optional): Whether to use parallel processing for the query.
633+
order (Order, optional): Ordering related options. Setting `disable=True` enhances performances.
630634
631635
Returns:
632636
list[InfrahubNode]: List of Nodes
@@ -645,6 +649,7 @@ async def all(
645649
prefetch_relationships=prefetch_relationships,
646650
property=property,
647651
parallel=parallel,
652+
order=order,
648653
)
649654

650655
@overload
@@ -664,6 +669,7 @@ async def filters(
664669
partial_match: bool = ...,
665670
property: bool = ...,
666671
parallel: bool = ...,
672+
order: Order | None = ...,
667673
**kwargs: Any,
668674
) -> list[SchemaType]: ...
669675

@@ -684,6 +690,7 @@ async def filters(
684690
partial_match: bool = ...,
685691
property: bool = ...,
686692
parallel: bool = ...,
693+
order: Order | None = ...,
687694
**kwargs: Any,
688695
) -> list[InfrahubNode]: ...
689696

@@ -703,6 +710,7 @@ async def filters(
703710
partial_match: bool = False,
704711
property: bool = False,
705712
parallel: bool = False,
713+
order: Order | None = None,
706714
**kwargs: Any,
707715
) -> list[InfrahubNode] | list[SchemaType]:
708716
"""Retrieve nodes of a given kind based on provided filters.
@@ -721,6 +729,7 @@ async def filters(
721729
prefetch_relationships (bool, optional): Flag to indicate whether to prefetch related node data.
722730
partial_match (bool, optional): Allow partial match of filter criteria for the query.
723731
parallel (bool, optional): Whether to use parallel processing for the query.
732+
order (Order, optional): Ordering related options. Setting `disable=True` enhances performances.
724733
**kwargs (Any): Additional filter criteria for the query.
725734
726735
Returns:
@@ -747,6 +756,7 @@ async def process_page(page_offset: int, page_number: int) -> tuple[dict, Proces
747756
prefetch_relationships=prefetch_relationships,
748757
partial_match=partial_match,
749758
property=property,
759+
order=order,
750760
)
751761
query = Query(query=query_data)
752762
response = await self.execute_graphql(
@@ -1670,6 +1680,7 @@ def all(
16701680
prefetch_relationships: bool = ...,
16711681
property: bool = ...,
16721682
parallel: bool = ...,
1683+
order: Order | None = ...,
16731684
) -> list[SchemaTypeSync]: ...
16741685

16751686
@overload
@@ -1688,6 +1699,7 @@ def all(
16881699
prefetch_relationships: bool = ...,
16891700
property: bool = ...,
16901701
parallel: bool = ...,
1702+
order: Order | None = ...,
16911703
) -> list[InfrahubNodeSync]: ...
16921704

16931705
def all(
@@ -1705,6 +1717,7 @@ def all(
17051717
prefetch_relationships: bool = False,
17061718
property: bool = False,
17071719
parallel: bool = False,
1720+
order: Order | None = None,
17081721
) -> list[InfrahubNodeSync] | list[SchemaTypeSync]:
17091722
"""Retrieve all nodes of a given kind
17101723
@@ -1721,6 +1734,7 @@ def all(
17211734
fragment (bool, optional): Flag to use GraphQL fragments for generic schemas.
17221735
prefetch_relationships (bool, optional): Flag to indicate whether to prefetch related node data.
17231736
parallel (bool, optional): Whether to use parallel processing for the query.
1737+
order (Order, optional): Ordering related options. Setting `disable=True` enhances performances.
17241738
17251739
Returns:
17261740
list[InfrahubNodeSync]: List of Nodes
@@ -1739,6 +1753,7 @@ def all(
17391753
prefetch_relationships=prefetch_relationships,
17401754
property=property,
17411755
parallel=parallel,
1756+
order=order,
17421757
)
17431758

17441759
def _process_nodes_and_relationships(
@@ -1793,6 +1808,7 @@ def filters(
17931808
partial_match: bool = ...,
17941809
property: bool = ...,
17951810
parallel: bool = ...,
1811+
order: Order | None = ...,
17961812
**kwargs: Any,
17971813
) -> list[SchemaTypeSync]: ...
17981814

@@ -1813,6 +1829,7 @@ def filters(
18131829
partial_match: bool = ...,
18141830
property: bool = ...,
18151831
parallel: bool = ...,
1832+
order: Order | None = ...,
18161833
**kwargs: Any,
18171834
) -> list[InfrahubNodeSync]: ...
18181835

@@ -1832,6 +1849,7 @@ def filters(
18321849
partial_match: bool = False,
18331850
property: bool = False,
18341851
parallel: bool = False,
1852+
order: Order | None = None,
18351853
**kwargs: Any,
18361854
) -> list[InfrahubNodeSync] | list[SchemaTypeSync]:
18371855
"""Retrieve nodes of a given kind based on provided filters.
@@ -1850,6 +1868,7 @@ def filters(
18501868
prefetch_relationships (bool, optional): Flag to indicate whether to prefetch related node data.
18511869
partial_match (bool, optional): Allow partial match of filter criteria for the query.
18521870
parallel (bool, optional): Whether to use parallel processing for the query.
1871+
order (Order, optional): Ordering related options. Setting `disable=True` enhances performances.
18531872
**kwargs (Any): Additional filter criteria for the query.
18541873
18551874
Returns:
@@ -1875,6 +1894,7 @@ def process_page(page_offset: int, page_number: int) -> tuple[dict, ProcessRelat
18751894
prefetch_relationships=prefetch_relationships,
18761895
partial_match=partial_match,
18771896
property=property,
1897+
order=order,
18781898
)
18791899
query = Query(query=query_data)
18801900
response = self.execute_graphql(

infrahub_sdk/graphql.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from typing import Any
44

5+
from pydantic import BaseModel
6+
57
VARIABLE_TYPE_MAPPING = ((str, "String!"), (int, "Int!"), (float, "Float!"), (bool, "Boolean!"))
68

79

@@ -15,6 +17,9 @@ def convert_to_graphql_as_string(value: str | bool | list) -> str:
1517
if isinstance(value, list):
1618
values_as_string = [convert_to_graphql_as_string(item) for item in value]
1719
return "[" + ", ".join(values_as_string) + "]"
20+
if isinstance(value, BaseModel):
21+
data = value.model_dump()
22+
return "{ " + ", ".join(f"{key}: {convert_to_graphql_as_string(val)}" for key, val in data.items()) + " }"
1823

1924
return str(value)
2025

infrahub_sdk/node.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from .client import InfrahubClient, InfrahubClientSync
2525
from .schema import AttributeSchemaAPI, MainSchemaTypesAPI, RelationshipSchemaAPI
26+
from .types import Order
2627

2728
# pylint: disable=too-many-lines
2829

@@ -977,6 +978,7 @@ def generate_query_data_init(
977978
include: list[str] | None = None,
978979
exclude: list[str] | None = None,
979980
partial_match: bool = False,
981+
order: Order | None = None,
980982
) -> dict[str, Any | dict]:
981983
data: dict[str, Any] = {
982984
"count": None,
@@ -985,6 +987,9 @@ def generate_query_data_init(
985987

986988
data["@filters"] = filters or {}
987989

990+
if order:
991+
data["@filters"]["order"] = order
992+
988993
if offset:
989994
data["@filters"]["offset"] = offset
990995

@@ -1176,9 +1181,16 @@ async def generate_query_data(
11761181
prefetch_relationships: bool = False,
11771182
partial_match: bool = False,
11781183
property: bool = False,
1184+
order: Order | None = None,
11791185
) -> dict[str, Any | dict]:
11801186
data = self.generate_query_data_init(
1181-
filters=filters, offset=offset, limit=limit, include=include, exclude=exclude, partial_match=partial_match
1187+
filters=filters,
1188+
offset=offset,
1189+
limit=limit,
1190+
include=include,
1191+
exclude=exclude,
1192+
partial_match=partial_match,
1193+
order=order,
11821194
)
11831195
data["edges"]["node"].update(
11841196
await self.generate_query_data_node(
@@ -1682,9 +1694,16 @@ def generate_query_data(
16821694
prefetch_relationships: bool = False,
16831695
partial_match: bool = False,
16841696
property: bool = False,
1697+
order: Order | None = None,
16851698
) -> dict[str, Any | dict]:
16861699
data = self.generate_query_data_init(
1687-
filters=filters, offset=offset, limit=limit, include=include, exclude=exclude, partial_match=partial_match
1700+
filters=filters,
1701+
offset=offset,
1702+
limit=limit,
1703+
include=include,
1704+
exclude=exclude,
1705+
partial_match=partial_match,
1706+
order=order,
16881707
)
16891708
data["edges"]["node"].update(
16901709
self.generate_query_data_node(

infrahub_sdk/schema/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ class BaseSchema(BaseModel):
264264
icon: str | None = None
265265
uniqueness_constraints: list[list[str]] | None = None
266266
documentation: str | None = None
267+
order_by: list[str] | None = None
267268

268269
@property
269270
def kind(self) -> str:

infrahub_sdk/testing/schemas/animal.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def schema_cat(self) -> NodeSchema:
8181
include_in_menu=True,
8282
inherit_from=[TESTING_ANIMAL],
8383
display_labels=["name__value", "breed__value", "color__value"],
84+
order_by=["name__value"],
8485
attributes=[
8586
Attr(name="breed", kind=AttributeKind.TEXT, optional=False),
8687
Attr(name="color", kind=AttributeKind.COLOR, default_value="#555555", optional=True),

infrahub_sdk/types.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from logging import Logger
55
from typing import TYPE_CHECKING, Any, Protocol, Union, runtime_checkable
66

7+
from pydantic import BaseModel
8+
79
if TYPE_CHECKING:
810
import httpx
911

@@ -64,3 +66,7 @@ def exception(self, event: str | None = None, *args: Any, **kw: Any) -> Any:
6466

6567

6668
InfrahubLoggers = Union[InfrahubLogger, Logger]
69+
70+
71+
class Order(BaseModel):
72+
disable: bool | None = None

tests/integration/test_infrahub_client.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,22 @@ async def test_get_all(self, client: InfrahubClient, base_dataset):
5959
nodes = await client.all(kind=TESTING_CAT)
6060
assert len(nodes) == 2
6161
assert isinstance(nodes[0], InfrahubNode)
62-
assert sorted([node.name.value for node in nodes]) == ["Bella", "Luna"]
62+
assert [node.name.value for node in nodes] == ["Bella", "Luna"]
63+
64+
# TODO enable these tests for infrahub version containing this commit
65+
# https://github.com/opsmill/infrahub/commit/5a4d6860196b5bfb51fb8a124f33125f4a0b6753
66+
# when we support testing against multiple infrahub versions.
67+
# async def test_get_all_no_order(self, client: InfrahubClient, base_dataset):
68+
# nodes = await client.all(kind=TESTING_CAT, order=Order(disable=True))
69+
# assert len(nodes) == 2
70+
# assert isinstance(nodes[0], InfrahubNode)
71+
# assert {node.name.value for node in nodes} == {"Bella", "Luna"}
72+
#
73+
# async def test_get_filters_no_order(self, client: InfrahubClient, base_dataset):
74+
# nodes = await client.filters(kind=TESTING_CAT, order=Order(disable=True))
75+
# assert len(nodes) == 2
76+
# assert isinstance(nodes[0], InfrahubNode)
77+
# assert {node.name.value for node in nodes} == {"Bella", "Luna"}
6378

6479
async def test_get_one(self, client: InfrahubClient, base_dataset, cat_luna, person_sophia):
6580
node1 = await client.get(kind=TESTING_CAT, id=cat_luna.id)

0 commit comments

Comments
 (0)