Skip to content

Commit

Permalink
fix: remove null from variables in gql query
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonas1312 committed Sep 29, 2023
1 parent 22d2c3d commit bdb0b25
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 17 deletions.
21 changes: 4 additions & 17 deletions src/kili/core/graphql/graphql_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,22 +234,9 @@ def _get_kili_app_version(self) -> Optional[str]:
return None

@classmethod
def _remove_keys_with_none_values(cls, variables: Dict) -> Dict:
"""Remove keys with None values from a nested dictionary."""
output_dict = {}
for key, value in variables.items():
if value is None:
continue

new_value = value
if isinstance(value, dict):
dict_without_nones = cls._remove_keys_with_none_values(value)
if len(dict_without_nones):
new_value = dict_without_nones

output_dict[key] = new_value

return output_dict
def _remove_nullable_inputs(cls, variables: Dict) -> Dict:
"""Remove nullable inputs from the variables."""
return {k: v for k, v in variables.items() if v is not None}

def execute(
self, query: Union[str, DocumentNode], variables: Optional[Dict] = None, **kwargs
Expand All @@ -262,7 +249,7 @@ def execute(
kwargs: additional arguments to pass to the GraphQL client
"""
document = query if isinstance(query, DocumentNode) else gql(query)
variables = self._remove_keys_with_none_values(variables) if variables else None
variables = self._remove_nullable_inputs(variables) if variables else None

try:
return self._execute_with_retries(document, variables, **kwargs)
Expand Down
73 changes: 73 additions & 0 deletions tests/unit/test_graphql_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from pathlib import Path
from tempfile import TemporaryDirectory
from time import time
from typing import Dict
from unittest import mock

import graphql
Expand Down Expand Up @@ -355,3 +356,75 @@ def mocked_backend_response(*args, **kwargs):
# Then
assert result["data"] == "all good"
assert mocked_execute.call_count == nb_times_called == 3


@pytest.mark.parametrize(
("variables", "expected"),
[
({"id": "123456"}, {"id": "123456"}),
({"id": None}, {}),
(
{
"project": {"id": "project_id"},
"asset": {"id": None},
"assetIn": ["123456"],
"status": "some_status",
"type": None,
},
{
"project": {"id": "project_id"},
"asset": {"id": None},
"assetIn": ["123456"],
"status": "some_status",
},
),
(
{
"id": None,
"searchQuery": "truc",
"shouldRelaunchKpiComputation": None,
"starred": True,
"updatedAtGte": None,
"updatedAtLte": None,
"createdAtGte": None,
"createdAtLte": None,
"tagIds": ["tag_id"],
},
{
"searchQuery": "truc",
"starred": True,
"tagIds": ["tag_id"],
},
),
( # assetwhere
{
"externalIdStrictlyIn": ["truc"],
"externalIdIn": None,
"honeypotMarkGte": None,
"honeypotMarkLte": 0.0,
"id": "fake_asset_id",
"metadata": {"key": None}, # this field is a JSON graphql type. It should be kept
"project": {"id": "fake_proj_id"},
"skipped": True,
"updatedAtLte": None,
},
{
"externalIdStrictlyIn": ["truc"],
"honeypotMarkLte": 0.0,
"id": "fake_asset_id",
"metadata": {"key": None},
"project": {"id": "fake_proj_id"},
"skipped": True,
},
),
],
)
def test_given_variables_when_i_remove_null_values_then_it_works(variables: Dict, expected: Dict):
# Given
_ = variables

# When
output = GraphQLClient._remove_nullable_inputs(variables)

# Then
assert output == expected

0 comments on commit bdb0b25

Please sign in to comment.