Skip to content

Commit

Permalink
Merge pull request #7 from RTIInternational/develop
Browse files Browse the repository at this point in the history
Updated plater to handle biolink.
  • Loading branch information
YaphetKG authored Nov 8, 2023
2 parents 02738f3 + 7f00e35 commit 3e2346c
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 23 deletions.
60 changes: 60 additions & 0 deletions PLATER/services/util/bl_helper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import asyncio
from functools import reduce
import re
import httpx
from PLATER.services.config import config

Expand Down Expand Up @@ -28,3 +29,62 @@ async def get_most_specific_concept(self, concept_list: list) -> list:
response = await asyncio.gather(*tasks, return_exceptions=False)
parents = list(reduce(lambda acc, value: acc + value, filter(lambda x: x, response), []))
return list(filter(lambda x: x not in parents, concept_list))

@staticmethod
def upgrade_BiolinkEntity(entity):
if entity.startswith("biolink."):
return entity
return "biolink." + BLHelper._pascal_case(entity)

@staticmethod
def upgrade_BiolinkRelation(biolink_relation):
if biolink_relation is None:
return None
if biolink_relation.startswith("biolink."):
return biolink_relation
return "biolink." + BLHelper._snake_case(biolink_relation)


@staticmethod
def _pascal_case(arg: str):
"""Convert string to PascalCase.
Non-alphanumeric characters are replaced with _.
"ThisCase" is replaced with "this_case".
"""
# replace _x with X
tmp = re.sub(
r"(?<=[a-zA-Z])_([a-z])",
lambda c: c.group(1).upper(),
arg
)
# upper-case first character
tmp = re.sub(
r"^[a-z]",
lambda c: c.group(0).upper(),
tmp
)
return tmp


def _snake_case(arg: str):
"""Convert string to snake_case.
Non-alphanumeric characters are replaced with _.
CamelCase is replaced with snake_case.
"""
# replace non-alphanumeric characters with _
tmp = re.sub(r'\W', '_', arg)
# replace X with _x
tmp = re.sub(
r'(?<=[a-z])[A-Z](?=[a-z])',
lambda c: '_' + c.group(0).lower(),
tmp
)
# lower-case first character
tmp = re.sub(
r'^[A-Z](?=[a-z])',
lambda c: c.group(0).lower(),
tmp
)
return tmp
7 changes: 4 additions & 3 deletions PLATER/services/util/drivers/redis_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from redis.exceptions import ConnectionError
from redis.backoff import NoBackoff
from redis.retry import Retry
from reasoner_converter.upgrading import upgrade_BiolinkRelation, upgrade_BiolinkEntity
# from PLATER.services.util.bl_helper import BLHelper

logger = LoggingUtil.init_logging(__name__,
config.get('logging_level'),
Expand Down Expand Up @@ -144,7 +144,7 @@ def create_TRAPI_kg_response(self, query_graph , results_dict):
if node_id not in collected_nodes:
new_node = {}
collected_nodes.add(node_id)
new_node['category'] = [upgrade_BiolinkEntity(x) for x in node['category']]
# new_node['category'] = [BLHelper.upgrade_BiolinkEntity(x) for x in node['category']]
new_node['name'] = node.get('name', '')
new_node['attributes'] = []
for key, value in node.items():
Expand All @@ -160,6 +160,7 @@ def create_TRAPI_kg_response(self, query_graph , results_dict):
for qg_id in edge_qg_ids:
edges = row[qg_id] if isinstance(row[qg_id], list) else [row[qg_id]]
edge_types = row[f'type__{qg_id}'] if isinstance(row[qg_id], list) else [row[f'type__{qg_id}']]
edge_types = [x.replace("biolink.", "biolink:") for x in edge_types]
id_pairs = row[f'id_pairs__{qg_id}']
index = 0
current_edge_binding = {qg_id: []}
Expand All @@ -169,7 +170,7 @@ def create_TRAPI_kg_response(self, query_graph , results_dict):
if edge_id not in collected_edges:
edge_in_query_graph = query_graph['edges'][qg_id]
source_real_id, target_real_id = id_pair
edge_type = upgrade_BiolinkRelation(edge_type)
# edge_type = BLHelper.upgrade_BiolinkRelation(edge_type)
new_edge = {
'subject': source_real_id,
'object': target_real_id,
Expand Down
32 changes: 12 additions & 20 deletions PLATER/services/util/drivers/redis_trapi_cypher_compiler.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Tools for compiling QGraph into Cypher query."""
import re
from reasoner_converter.downgrading import downgrade_BiolinkEntity, downgrade_BiolinkPredicate
from reasoner_converter.upgrading import upgrade_BiolinkEntity, upgrade_BiolinkRelation
#from reasoner_converter.downgrading import downgrade_BiolinkEntity, downgrade_BiolinkPredicate
# from reasoner_converter.upgrading import upgrade_BiolinkEntity, upgrade_BiolinkRelation
#from PLATER.services.util.bl_helper import BLHelper


def cypher_prop_string(value):
Expand All @@ -21,7 +22,7 @@ def __init__(self, node, node_id ,anonymous=False):
"""Create a node reference."""
node = dict(node)
name = f'{node_id}' if not anonymous else ''
labels = node.pop('category', 'named_thing')
labels = node.pop('category', 'biolink.NamedThing')
if not isinstance(labels, list):
labels = [labels]
props = {}
Expand All @@ -41,15 +42,9 @@ def __init__(self, node, node_id ,anonymous=False):
self.has_curie = True
label_filters = []
if labels:
biolink_regex = "^biolink:[A-Z][a-zA-Z]*$"
for label in labels:
label_filters.append(f"'{label}' in {name}.category")
is_biolinkified = re.match(biolink_regex, label)
if is_biolinkified:
other_label = downgrade_BiolinkEntity(label)
else:
other_label = upgrade_BiolinkEntity(label)
label_filters.append(f"'{other_label}' in {name}.category")
other_label = label.replace('biolink:', 'biolink.')
label_filters.append(f"`{other_label}` in labels(`{name}`)")
self._filters = ''
if len(curie_filters):
filters = '( ' + ' OR '.join(curie_filters) + ')'
Expand All @@ -72,7 +67,7 @@ def __str__(self):
"""Return the cypher node reference."""
self._num += 1
if self._num == 1:
label = f':`{self.labels[0]}`' if self.labels else ''
label = f':`{self.labels[0].replace("biolink:", "biolink.")}`' if self.labels else ''
return f'{self.name}' + label + f'{self.prop_string}' # + ''.join(f':`{label}`' for label in self.labels)
return self.name

Expand Down Expand Up @@ -109,14 +104,11 @@ def __init__(self, edge, edge_id, anonymous=False):
filters = ''
elif isinstance(edge['predicate'], list):
filters = []
biolink_predicate_regex = "^biolink:[a-z][a-z_]*$"
# biolink_predicate_regex = "^biolink:[a-z][a-z_]*$"
for predicate in edge['predicate']:
is_biolink_predicate = re.match(biolink_predicate_regex, predicate)
filters.append(f'type({name}) = "{predicate}"')
if is_biolink_predicate:
other_predicate = downgrade_BiolinkPredicate(predicate)
else:
other_predicate = upgrade_BiolinkRelation(predicate)
# is_biolink_predicate = re.match(biolink_predicate_regex, predicate)
# filters.append(f'type({name}) = "{predicate}"')
other_predicate = predicate.replace('biolink:', 'biolink.')
filters.append(f'type({name}) = "{other_predicate}" ')
filters = ' OR '.join(filters)
label = None
Expand All @@ -136,7 +128,7 @@ def __str__(self):
"""Return the cypher edge reference."""
self._num += 1
if self._num == 1:
label = f':`{self.label}`' if self.label else ''
label = f':`{self.label.replace("biolink:", "biolink.")}`' if self.label else ''
innards = f'{self.name}{label}'
else:
innards = self.name
Expand Down

0 comments on commit 3e2346c

Please sign in to comment.