diff --git a/changelog/10.fixed.md b/changelog/10.fixed.md new file mode 100644 index 00000000..6fc778c5 --- /dev/null +++ b/changelog/10.fixed.md @@ -0,0 +1 @@ +prefix and address attribute filters are now available in the Python SDK \ No newline at end of file diff --git a/changelog/30.fixed.md b/changelog/30.fixed.md new file mode 100644 index 00000000..5cbce266 --- /dev/null +++ b/changelog/30.fixed.md @@ -0,0 +1 @@ +Queries using isnull as a filter are now supported by the Python SDK \ No newline at end of file diff --git a/changelog/9.changed.md b/changelog/9.changed.md new file mode 100644 index 00000000..92417330 --- /dev/null +++ b/changelog/9.changed.md @@ -0,0 +1 @@ +Query filters are not validated locally anymore, the validation will be done on the server side instead. \ No newline at end of file diff --git a/infrahub_sdk/__init__.py b/infrahub_sdk/__init__.py index 4d44fdd2..624f7ee0 100644 --- a/infrahub_sdk/__init__.py +++ b/infrahub_sdk/__init__.py @@ -10,7 +10,6 @@ from infrahub_sdk.exceptions import ( AuthenticationError, Error, - FilterNotFoundError, GraphQLError, NodeNotFoundError, ServerNotReachableError, @@ -50,7 +49,6 @@ "InfrahubNodeSync", "InfrahubRepositoryConfig", "InfrahubSchema", - "FilterNotFoundError", "generate_uuid", "GenericSchema", "GraphQLQueryAnalyzer", diff --git a/infrahub_sdk/client.py b/infrahub_sdk/client.py index 972c0d73..ba7f883b 100644 --- a/infrahub_sdk/client.py +++ b/infrahub_sdk/client.py @@ -623,9 +623,6 @@ async def filters( node = InfrahubNode(client=self, schema=schema, branch=branch) filters = kwargs - if filters: - node.validate_filters(filters=filters) - nodes: list[InfrahubNode] = [] related_nodes: list[InfrahubNode] = [] @@ -1680,9 +1677,6 @@ def filters( node = InfrahubNodeSync(client=self, schema=schema, branch=branch) filters = kwargs - if filters: - node.validate_filters(filters=filters) - nodes: list[InfrahubNodeSync] = [] related_nodes: list[InfrahubNodeSync] = [] diff --git a/infrahub_sdk/ctl/utils.py b/infrahub_sdk/ctl/utils.py index 032a4d2b..73eb3e6d 100644 --- a/infrahub_sdk/ctl/utils.py +++ b/infrahub_sdk/ctl/utils.py @@ -18,7 +18,6 @@ from infrahub_sdk.exceptions import ( AuthenticationError, Error, - FilterNotFoundError, GraphQLError, NodeNotFoundError, SchemaNotFoundError, @@ -57,7 +56,7 @@ def handle_exception(exc: Exception, console: Console, exit_code: int): if isinstance(exc, GraphQLError): print_graphql_errors(console=console, errors=exc.errors) raise typer.Exit(code=exit_code) - if isinstance(exc, (SchemaNotFoundError, NodeNotFoundError, FilterNotFoundError)): + if isinstance(exc, (SchemaNotFoundError, NodeNotFoundError)): console.print(f"[red]Error: {str(exc)}") raise typer.Exit(code=exit_code) diff --git a/infrahub_sdk/exceptions.py b/infrahub_sdk/exceptions.py index b9628beb..1aa92e58 100644 --- a/infrahub_sdk/exceptions.py +++ b/infrahub_sdk/exceptions.py @@ -87,15 +87,6 @@ def __str__(self) -> str: """ -class FilterNotFoundError(Error): - def __init__(self, identifier: str, kind: str, message: Optional[str] = None, filters: Optional[list[str]] = None): - self.identifier = identifier - self.kind = kind - self.filters = filters or [] - self.message = message or f"{identifier!r} is not a valid filter for {self.kind!r} ({', '.join(self.filters)})." - super().__init__(self.message) - - class InfrahubCheckNotFoundError(Error): def __init__(self, name: str, message: Optional[str] = None): self.message = message or f"The requested InfrahubCheck '{name}' was not found." diff --git a/infrahub_sdk/node.py b/infrahub_sdk/node.py index 66b9bb0f..639333ea 100644 --- a/infrahub_sdk/node.py +++ b/infrahub_sdk/node.py @@ -9,7 +9,6 @@ from infrahub_sdk.exceptions import ( Error, FeatureNotSupportedError, - FilterNotFoundError, NodeNotFoundError, UninitializedError, ) @@ -987,26 +986,6 @@ def generate_query_data_init( return data - def validate_filters(self, filters: Optional[dict[str, Any]] = None) -> bool: - if not filters: - return True - - for filter_name in filters.keys(): - found = False - for filter_schema in self._schema.filters: - if filter_name == filter_schema.name: - found = True - break - if not found: - valid_filters = [entry.name for entry in self._schema.filters] - raise FilterNotFoundError( - identifier=filter_name, - kind=self._schema.kind, - filters=valid_filters, - ) - - return True - def extract(self, params: dict[str, str]) -> dict[str, Any]: """Extract some datapoints defined in a flat notation.""" result: dict[str, Any] = {} diff --git a/infrahub_sdk/protocols_base.py b/infrahub_sdk/protocols_base.py index b23b15c2..e2520d01 100644 --- a/infrahub_sdk/protocols_base.py +++ b/infrahub_sdk/protocols_base.py @@ -149,8 +149,6 @@ def is_resource_pool(self) -> bool: ... def get_raw_graphql_data(self) -> Optional[dict]: ... - def validate_filters(self, filters: Optional[dict[str, Any]] = None) -> bool: ... - def extract(self, params: dict[str, str]) -> dict[str, Any]: ... diff --git a/tests/unit/sdk/test_client.py b/tests/unit/sdk/test_client.py index 50dc0b34..edd96f3a 100644 --- a/tests/unit/sdk/test_client.py +++ b/tests/unit/sdk/test_client.py @@ -4,7 +4,7 @@ from pytest_httpx import HTTPXMock from infrahub_sdk import InfrahubClient, InfrahubClientSync -from infrahub_sdk.exceptions import FilterNotFoundError, NodeNotFoundError +from infrahub_sdk.exceptions import NodeNotFoundError from infrahub_sdk.node import InfrahubNode, InfrahubNodeSync async_client_methods = [method for method in dir(InfrahubClient) if not method.startswith("_")] @@ -329,19 +329,6 @@ async def test_method_get_found_many( clients.sync.get(kind="CoreRepository", id="bfae43e8-5ebb-456c-a946-bf64e930710a") -@pytest.mark.parametrize("client_type", client_types) -async def test_method_get_invalid_filter(httpx_mock: HTTPXMock, clients, mock_schema_query_01, client_type): # pylint: disable=unused-argument - with pytest.raises(FilterNotFoundError) as excinfo: - if client_type == "standard": - await clients.standard.get(kind="CoreRepository", name__name="infrahub-demo-core") - else: - clients.sync.get(kind="CoreRepository", name__name="infrahub-demo-core") - assert isinstance(excinfo.value.message, str) - assert "'name__name' is not a valid filter for 'CoreRepository'" in excinfo.value.message - assert "default_branch__value" in excinfo.value.message - assert "default_branch__value" in excinfo.value.filters - - @pytest.mark.parametrize("client_type", client_types) async def test_method_filters_many(httpx_mock: HTTPXMock, clients, mock_query_repository_page1_1, client_type): # pylint: disable=unused-argument if client_type == "standard":