trustgraph/trustgraph-flow/trustgraph/query/triples/cassandra/service.py
cybermaggedon ccaec88a72
Feature/consolidate cassandra config (#483)
* Cassandra consolidation of parameters

* New Cassandra configuration helper

* Implemented Cassanda config refactor

* New tests
2025-09-03 23:41:22 +01:00

164 lines
5.5 KiB
Python
Executable file

"""
Triples query service. Input is a (s, p, o) triple, some values may be
null. Output is a list of triples.
"""
import logging
from .... direct.cassandra import TrustGraph
from .... schema import TriplesQueryRequest, TriplesQueryResponse, Error
from .... schema import Value, Triple
from .... base import TriplesQueryService
from .... base.cassandra_config import add_cassandra_args, resolve_cassandra_config
# Module logger
logger = logging.getLogger(__name__)
default_ident = "triples-query"
class Processor(TriplesQueryService):
def __init__(self, **params):
# Use new parameter names, fall back to old for compatibility
cassandra_host = params.get("cassandra_host", params.get("graph_host"))
cassandra_username = params.get("cassandra_username", params.get("graph_username"))
cassandra_password = params.get("cassandra_password", params.get("graph_password"))
# Resolve configuration with environment variable fallback
hosts, username, password = resolve_cassandra_config(
host=cassandra_host,
username=cassandra_username,
password=cassandra_password
)
super(Processor, self).__init__(
**params | {
"cassandra_host": ','.join(hosts),
"cassandra_username": username,
}
)
self.graph_host = hosts
self.username = username
self.password = password
self.table = None
def create_value(self, ent):
if ent.startswith("http://") or ent.startswith("https://"):
return Value(value=ent, is_uri=True)
else:
return Value(value=ent, is_uri=False)
async def query_triples(self, query):
try:
table = (query.user, query.collection)
if table != self.table:
if self.username and self.password:
self.tg = TrustGraph(
hosts=self.graph_host,
keyspace=query.user, table=query.collection,
username=self.username, password=self.password
)
else:
self.tg = TrustGraph(
hosts=self.graph_host,
keyspace=query.user, table=query.collection,
)
self.table = table
triples = []
if query.s is not None:
if query.p is not None:
if query.o is not None:
resp = self.tg.get_spo(
query.s.value, query.p.value, query.o.value,
limit=query.limit
)
triples.append((query.s.value, query.p.value, query.o.value))
else:
resp = self.tg.get_sp(
query.s.value, query.p.value,
limit=query.limit
)
for t in resp:
triples.append((query.s.value, query.p.value, t.o))
else:
if query.o is not None:
resp = self.tg.get_os(
query.o.value, query.s.value,
limit=query.limit
)
for t in resp:
triples.append((query.s.value, t.p, query.o.value))
else:
resp = self.tg.get_s(
query.s.value,
limit=query.limit
)
for t in resp:
triples.append((query.s.value, t.p, t.o))
else:
if query.p is not None:
if query.o is not None:
resp = self.tg.get_po(
query.p.value, query.o.value,
limit=query.limit
)
for t in resp:
triples.append((t.s, query.p.value, query.o.value))
else:
resp = self.tg.get_p(
query.p.value,
limit=query.limit
)
for t in resp:
triples.append((t.s, query.p.value, t.o))
else:
if query.o is not None:
resp = self.tg.get_o(
query.o.value,
limit=query.limit
)
for t in resp:
triples.append((t.s, t.p, query.o.value))
else:
resp = self.tg.get_all(
limit=query.limit
)
for t in resp:
triples.append((t.s, t.p, t.o))
triples = [
Triple(
s=self.create_value(t[0]),
p=self.create_value(t[1]),
o=self.create_value(t[2])
)
for t in triples
]
return triples
except Exception as e:
logger.error(f"Exception querying triples: {e}", exc_info=True)
raise e
@staticmethod
def add_args(parser):
TriplesQueryService.add_args(parser)
add_cassandra_args(parser)
def run():
Processor.launch(default_ident, __doc__)