diff --git a/apis_core/apis_entities/triple_configs/E21_PersonFromDNB.toml b/apis_core/apis_entities/triple_configs/E21_PersonFromDNB.toml new file mode 100644 index 000000000..d9a23cb8d --- /dev/null +++ b/apis_core/apis_entities/triple_configs/E21_PersonFromDNB.toml @@ -0,0 +1,13 @@ +[[filters]] +"rdf:type" = "gndo:DifferentiatedPerson" + +[attributes] +forename = ["gndo:forename", "gndo:preferredNameEntityForThePerson"] +alternative_names = "gndo:variantNameForThePerson" +surname = ["gndo:surname", "gndo:preferredNameEntityForThePerson"] +start_date_written = "gndo:dateOfBirth" +end_date_written = "gndo:dateOfDeath" +same_as = "owl:sameAs" +profession = "gndo:professionOrOccupation" + +relations = ["gndo:placeOfDeath", "gndo:placeOfBirth"] diff --git a/apis_core/utils/rdf2.py b/apis_core/utils/rdf2.py new file mode 100644 index 000000000..0a8904a41 --- /dev/null +++ b/apis_core/utils/rdf2.py @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: 2025 Birger Schacht +# SPDX-License-Identifier: MIT + +import logging +from collections import defaultdict + +from rdflib import Graph, BNode +from apis_core.utils.settings import dict_from_toml_directory + +from AcdhArcheAssets.uri_norm_rules import get_normalized_uri + +logger = logging.getLogger(__name__) + + +def find_matching_config(graph: Graph) -> dict | None: + triple_configs = dict_from_toml_directory("triple_configs") + for path, config in triple_configs.items(): + for _filter in config.get("filters", []): + triples = [(None, graph.namespace_manager.expand_curie(predicate), graph.namespace_manager.expand_curie(obj)) for predicate, obj in _filter.items()] + triples = [triple in graph for triple in triples] + if all(triples): + logger.debug("Using %s for parsing graph", path) + return config + return None + + +def get_something_from_uri(uri: str) -> dict | None: + uri = get_normalized_uri(uri) + graph = Graph() + graph.parse(uri) + + if config := find_matching_config(graph): + result = defaultdict(list) + result["relations"] = defaultdict(list) + + for attribute, curies in config.get("attributes", {}).items(): + if isinstance(curies, str): + curies = [curies] + for curie in curies: + matches = graph[:graph.namespace_manager.expand_curie(curie)] + for pred, obj in matches: + if isinstance(obj, BNode): + value = [x.toPython() for x in graph.objects(subject=obj)] + else: + value = obj.toPython() + + if attribute == "relations": + if isinstance(value, list): + result["relations"][curie].extend(value) + else: + result["relations"][curie].append(value) + else: + if isinstance(value, list): + result[attribute].extend(value) + else: + result[attribute].append(value) + return dict(result) + return None