Skip to content

Bring by_name() up to parity with the openMINDS implementation #131

Description

@apdavison

fairgraph defines by_name() on KGObject, overriding the version openMINDS generates. openMINDS generates it per class — 86 of the v4 class modules — while fairgraph's lands on every class.

fairgraph adds what openMINDS cannot do (query the KG via client, space, release_status, follow_links), but loses capability in the process.

Proposed approach: let client decide

Make the presence of client select the backend explicitly, and document it as the contract:

  • by_name(name) — searches the openMINDS instance library and returns terms with their semantic IRIs (https://openminds.om-i.org/instances/species/musMusculus), behaving exactly as the openMINDS method does. Implemented by delegating to super().by_name(...) rather than reimplementing.
  • by_name(name, client) — searches the Knowledge Graph and returns instances with their UUID-based ids (https://kg.ebrains.eu/api/instances/d9875ebd-…). Callers may legitimately want either, which is why delegation cannot simply replace the KG path.

The class sets line up exactly: all 86 v4 modules defining by_name also define instances, and none defines one without the other. So "has an openMINDS by_name" and "has an instance library" are the same set, and super().by_name is reachable through the MRO precisely where there is something to delegate to — Species and License have it, Person has neither it nor instances(). The existing elif hasattr(cls, "instances") guard already discriminates the same way; it just reimplements instead of calling.

Delegating settles the instance-library side of the gaps below at a stroke, and supersedes the code patched in #130.

The gaps

1. The KG search covers one property, not seven. The docstring says the search includes name, lookup_label, family_name, full_name, short_name, abbreviation and synonyms, but the loop breaks at the first property the class has:

for prop_name in namelike_properties:
    if prop_name in cls.property_names:
        kwargs[prop_name] = name
        break

Since short_name sits fifth, and all 24 classes that have it also have an earlier name-like property, no class is ever searched on short_name. Confirmed against pre-production: License.by_name("CC-BY-NC-4.0") finds nothing, while License.from_alias("CC-BY-NC-4.0") finds it. The match="equals" post-filter does check all seven properties, but it can only narrow what the single-property query returned.

Note that KG filters are per-property with no documented way to OR across them, so searching all name-like properties means either several queries merged or a regex.

2. case_sensitive is missing. Delegation supplies it for the instance library. For the KG path the backends disagree: openMINDS defaults to case_sensitive=True, whereas KG filters are case-insensitive — full_name matches when given exactly, lowercased or uppercased. That is undocumented in the KG filter documentation, so it is observed rather than guaranteed. Honouring case_sensitive=True against the KG therefore means post-filtering client-side.

3. ignore_accents is missing. Again supplied for the instance library by delegation, where openMINDS implements it with a translation table for diacritics and special letters (ßss, œoe), which matters for neuroscience terminology. The KG offers nothing equivalent and documents no accent handling, though the REGEX filter operator could carry a generated character-class pattern. The alternative is widening the query and filtering locally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions