Skip to content

Commit 9ab7f70

Browse files
committed
Extend by_name() method.
(a) if called without a client object, does the equivalent of the openMINDS-Python `by_name()` method, looking in local instance library (b) looks in "lookup_label", "family_name", "full_name", "short_name", "synonyms" properties in addition to "name"
1 parent 5e27101 commit 9ab7f70

File tree

1 file changed

+38
-9
lines changed

1 file changed

+38
-9
lines changed

fairgraph/kgobject.py

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ def dump(self, file_path, indent=2):
840840
def by_name(
841841
cls,
842842
name: str,
843-
client: KGClient,
843+
client: Optional[KGClient] = None,
844844
match: str = "equals",
845845
all: bool = False,
846846
space: Optional[str] = None,
@@ -851,10 +851,12 @@ def by_name(
851851
"""
852852
Retrieve an instance from the Knowledge Graph based on its name.
853853
854-
Note that not all metadata classes have a name property.
854+
This includes properties "name", "lookup_label", "family_name", "full_name", "short_name", and "synonyms".
855+
856+
Note that not all metadata classes have a name.
855857
856858
Args:
857-
name (str): a string to search for in the name property.
859+
name (str): a string to search for.
858860
client: a KGClient
859861
match (str, optional): either "equals" (exact match - default) or "contains".
860862
all (bool, optional): Whether to return all objects that match the name, or only the first. Defaults to False.
@@ -866,13 +868,40 @@ def by_name(
866868
"""
867869
release_status = handle_scope_keyword(scope, release_status)
868870
# todo: move this to openminds generation, and include only in those subclasses
869-
# that have a name
870-
# todo: also count 'lookup_name', "family_name", "given_name" as a name
871-
objects = cls.list(
872-
client, space=space, release_status=release_status, api="query", name=name, follow_links=follow_links
873-
)
871+
# that have a name-like property
872+
namelike_properties = ("name", "lookup_label", "family_name", "full_name", "short_name", "synonyms")
873+
objects = []
874+
if client:
875+
kwargs = dict(space=space, release_status=release_status, api="query", follow_links=follow_links)
876+
for prop_name in namelike_properties:
877+
if prop_name in cls.property_names:
878+
kwargs[prop_name] = name
879+
break
880+
objects = cls.list(client, **kwargs)
881+
elif hasattr(cls, "instances"): # controlled terms, etc.
882+
if cls._instance_lookup is None:
883+
cls._instance_lookup = {}
884+
for instance in cls.instances():
885+
found = False
886+
for prop_name in namelike_properties[-1]: # handle 'synonyms' separately
887+
if hasattr(instance, prop_name):
888+
cls._instance_lookup[getattr(instance, prop_name)] = instance
889+
found = True
890+
break
891+
if (not found) and instance.synonyms:
892+
for synonym in instance.synonyms:
893+
cls._instance_lookup[synonym] = instance
894+
obj = cls._instance_lookup.get(name, None)
895+
if obj:
896+
objects.append(obj)
874897
if match == "equals":
875-
objects = [obj for obj in objects if hasattr(obj, "name") and obj.name == name]
898+
objects = [
899+
obj for obj in objects
900+
if any(
901+
getattr(obj, prop_name, None) == name
902+
for prop_name in namelike_properties
903+
)
904+
]
876905
if len(objects) == 0:
877906
return None
878907
elif len(objects) == 1:

0 commit comments

Comments
 (0)