Skip to content

Commit fb268e5

Browse files
committed
Order of retrieved nodes can be disabled
1 parent d617bdd commit fb268e5

File tree

7 files changed

+65
-4
lines changed

7 files changed

+65
-4
lines changed

infrahub_sdk/client.py

Lines changed: 17 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, OrderModel, SyncRequester
5555
from .utils import decode_json, is_valid_uuid
5656

5757
if TYPE_CHECKING:
@@ -540,6 +540,7 @@ async def all(
540540
fragment: bool = ...,
541541
prefetch_relationships: bool = ...,
542542
property: bool = ...,
543+
order: OrderModel | None = ...,
543544
) -> list[SchemaType]: ...
544545

545546
@overload
@@ -557,6 +558,7 @@ async def all(
557558
fragment: bool = ...,
558559
prefetch_relationships: bool = ...,
559560
property: bool = ...,
561+
order: OrderModel | None = ...,
560562
) -> list[InfrahubNode]: ...
561563

562564
async def all(
@@ -573,6 +575,7 @@ async def all(
573575
fragment: bool = False,
574576
prefetch_relationships: bool = False,
575577
property: bool = False,
578+
order: OrderModel | None = None,
576579
) -> list[InfrahubNode] | list[SchemaType]:
577580
"""Retrieve all nodes of a given kind
578581
@@ -605,6 +608,7 @@ async def all(
605608
fragment=fragment,
606609
prefetch_relationships=prefetch_relationships,
607610
property=property,
611+
order=order,
608612
)
609613

610614
@overload
@@ -623,6 +627,7 @@ async def filters(
623627
prefetch_relationships: bool = ...,
624628
partial_match: bool = ...,
625629
property: bool = ...,
630+
order: OrderModel | None = ...,
626631
**kwargs: Any,
627632
) -> list[SchemaType]: ...
628633

@@ -642,6 +647,7 @@ async def filters(
642647
prefetch_relationships: bool = ...,
643648
partial_match: bool = ...,
644649
property: bool = ...,
650+
order: OrderModel | None = ...,
645651
**kwargs: Any,
646652
) -> list[InfrahubNode]: ...
647653

@@ -660,6 +666,7 @@ async def filters(
660666
prefetch_relationships: bool = False,
661667
partial_match: bool = False,
662668
property: bool = False,
669+
order: OrderModel | None = None,
663670
**kwargs: Any,
664671
) -> list[InfrahubNode] | list[SchemaType]:
665672
"""Retrieve nodes of a given kind based on provided filters.
@@ -710,6 +717,7 @@ async def filters(
710717
prefetch_relationships=prefetch_relationships,
711718
partial_match=partial_match,
712719
property=property,
720+
order=order,
713721
)
714722
query = Query(query=query_data)
715723
response = await self.execute_graphql(
@@ -1564,6 +1572,7 @@ def all(
15641572
fragment: bool = ...,
15651573
prefetch_relationships: bool = ...,
15661574
property: bool = ...,
1575+
order: OrderModel | None = ...,
15671576
) -> list[SchemaTypeSync]: ...
15681577

15691578
@overload
@@ -1581,6 +1590,7 @@ def all(
15811590
fragment: bool = ...,
15821591
prefetch_relationships: bool = ...,
15831592
property: bool = ...,
1593+
order: OrderModel | None = ...,
15841594
) -> list[InfrahubNodeSync]: ...
15851595

15861596
def all(
@@ -1597,6 +1607,7 @@ def all(
15971607
fragment: bool = False,
15981608
prefetch_relationships: bool = False,
15991609
property: bool = False,
1610+
order: OrderModel | None = None,
16001611
) -> list[InfrahubNodeSync] | list[SchemaTypeSync]:
16011612
"""Retrieve all nodes of a given kind
16021613
@@ -1629,6 +1640,7 @@ def all(
16291640
fragment=fragment,
16301641
prefetch_relationships=prefetch_relationships,
16311642
property=property,
1643+
order=order,
16321644
)
16331645

16341646
def _process_nodes_and_relationships(
@@ -1682,6 +1694,7 @@ def filters(
16821694
prefetch_relationships: bool = ...,
16831695
partial_match: bool = ...,
16841696
property: bool = ...,
1697+
order: OrderModel | None = ...,
16851698
**kwargs: Any,
16861699
) -> list[SchemaTypeSync]: ...
16871700

@@ -1701,6 +1714,7 @@ def filters(
17011714
prefetch_relationships: bool = ...,
17021715
partial_match: bool = ...,
17031716
property: bool = ...,
1717+
order: OrderModel | None = ...,
17041718
**kwargs: Any,
17051719
) -> list[InfrahubNodeSync]: ...
17061720

@@ -1719,6 +1733,7 @@ def filters(
17191733
prefetch_relationships: bool = False,
17201734
partial_match: bool = False,
17211735
property: bool = False,
1736+
order: OrderModel | None = None,
17221737
**kwargs: Any,
17231738
) -> list[InfrahubNodeSync] | list[SchemaTypeSync]:
17241739
"""Retrieve nodes of a given kind based on provided filters.
@@ -1769,6 +1784,7 @@ def filters(
17691784
prefetch_relationships=prefetch_relationships,
17701785
partial_match=partial_match,
17711786
property=property,
1787+
order=order,
17721788
)
17731789
query = Query(query=query_data)
17741790
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 OrderModel
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: OrderModel | 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: OrderModel | 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: OrderModel | 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 OrderModel(BaseModel):
72+
disable: bool | None = None

tests/integration/test_infrahub_client.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from infrahub_sdk.schema import ProfileSchemaAPI
1111
from infrahub_sdk.testing.docker import TestInfrahubDockerClient
1212
from infrahub_sdk.testing.schemas.animal import TESTING_ANIMAL, TESTING_CAT, TESTING_DOG, TESTING_PERSON, SchemaAnimal
13+
from infrahub_sdk.types import OrderModel
1314

1415
if TYPE_CHECKING:
1516
from infrahub_sdk import InfrahubClient
@@ -59,7 +60,19 @@ async def test_get_all(self, client: InfrahubClient, base_dataset):
5960
nodes = await client.all(kind=TESTING_CAT)
6061
assert len(nodes) == 2
6162
assert isinstance(nodes[0], InfrahubNode)
62-
assert sorted([node.name.value for node in nodes]) == ["Bella", "Luna"]
63+
assert [node.name.value for node in nodes] == ["Bella", "Luna"]
64+
65+
async def test_get_all_no_order(self, client: InfrahubClient, base_dataset):
66+
nodes = await client.all(kind=TESTING_CAT, order=OrderModel(disable=True))
67+
assert len(nodes) == 2
68+
assert isinstance(nodes[0], InfrahubNode)
69+
assert {node.name.value for node in nodes} == {"Bella", "Luna"}
70+
71+
async def test_get_filters_no_order(self, client: InfrahubClient, base_dataset):
72+
nodes = await client.filters(kind=TESTING_CAT, order=OrderModel(disable=True))
73+
assert len(nodes) == 2
74+
assert isinstance(nodes[0], InfrahubNode)
75+
assert {node.name.value for node in nodes} == {"Bella", "Luna"}
6376

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

0 commit comments

Comments
 (0)