Coverage for graphqler / compiler / resolvers / utils.py: 96%
24 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-20 10:09 -0400
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-20 10:09 -0400
1from Levenshtein import distance
2from graphqler.config import MAX_LEVENSHTEIN_THRESHOLD
5def find_closest_string_leveshtein(strings: list[str], target: str, threshold: float) -> str:
6 """Finds the closest string to the target string given a threshold. If none are found, returns ""
8 Args:
9 strings (list[str]): The list of strings to search for
10 target (str): The target string to search for
11 threshold (float): The treshold value
13 Returns:
14 str: Returns a string if it's within the threshold, otherwise returns ""
15 """
16 closest_distance = threshold + 1
17 closest_string = ""
18 for string in strings:
19 dist = distance(string, target)
20 if dist <= threshold and dist < closest_distance:
21 closest_distance = dist
22 closest_string = string
23 return closest_string
26def find_closest_string(strings: list[str], target: str) -> str:
27 """Finds the closest string to the target string
29 Args:
30 strings (list[str]): The list of strings (in our case, object names)
31 target (str): The target (in our case, either the field name or the query/mutation name)
33 Returns:
34 str: The found matching string, or "" if nothing close is found
35 """
36 # Do some pre-procssing first (remove underscores, lowercase)
37 target = target.lower().replace("_", "")
38 lookup = {}
39 for string in strings:
40 lookup[string.lower().replace("_", "")] = string
42 found_similar_strings = []
43 for normalized_string, string in lookup.items():
44 if normalized_string in target:
45 found_similar_strings.append(string)
46 if len(found_similar_strings) == 0:
47 return ""
48 closest_string = find_closest_string_leveshtein(found_similar_strings, target, MAX_LEVENSHTEIN_THRESHOLD)
49 return closest_string