|
@@ -67,7 +67,7 @@ class VirtuosoEntityStore:
|
|
|
) as (read_stream, write_stream):
|
|
) as (read_stream, write_stream):
|
|
|
async with ClientSession(read_stream, write_stream) as session:
|
|
async with ClientSession(read_stream, write_stream) as session:
|
|
|
await session.initialize()
|
|
await session.initialize()
|
|
|
- result = await session.call_tool("sparql_query", {"query": query})
|
|
|
|
|
|
|
+ result = await session.call_tool("sparql_query", {"input": {"query": query}})
|
|
|
if result.isError:
|
|
if result.isError:
|
|
|
return None
|
|
return None
|
|
|
payload = result.structuredContent or _content_to_json(result.content)
|
|
payload = result.structuredContent or _content_to_json(result.content)
|
|
@@ -103,17 +103,23 @@ def _build_sparql_query(literal: str) -> str:
|
|
|
esc = literal.replace("\\", "\\\\").replace("\"", "\\\"")
|
|
esc = literal.replace("\\", "\\\\").replace("\"", "\\\"")
|
|
|
return f"""
|
|
return f"""
|
|
|
PREFIX atlas: <{PREFIX_ATLAS}>
|
|
PREFIX atlas: <{PREFIX_ATLAS}>
|
|
|
-SELECT ?entity ?label ?type ?mid WHERE {{
|
|
|
|
|
|
|
+SELECT ?entity ?label ?type ?mid ?desc ?rawWd ?rawTrends WHERE {{
|
|
|
GRAPH <{ATLAS_GRAPH_IRI}> {{
|
|
GRAPH <{ATLAS_GRAPH_IRI}> {{
|
|
|
- ?entity atlas:canonicalLabel ?label .
|
|
|
|
|
- OPTIONAL {{ ?entity atlas:entityType ?type. }}
|
|
|
|
|
|
|
+ ?entity a atlas:Entity ;
|
|
|
|
|
+ atlas:canonicalLabel ?label .
|
|
|
|
|
+ OPTIONAL {{ ?entity atlas:canonicalDescription ?desc . }}
|
|
|
|
|
+ OPTIONAL {{ ?entity atlas:rawWikidataJson ?rawWd . }}
|
|
|
|
|
+ OPTIONAL {{ ?entity atlas:rawTrendsJson ?rawTrends . }}
|
|
|
|
|
+
|
|
|
OPTIONAL {{
|
|
OPTIONAL {{
|
|
|
- ?entity atlas:hasExternalIdentifier ?identifier .
|
|
|
|
|
- ?identifier atlas:identifierType "mid" .
|
|
|
|
|
- ?identifier atlas:identifierValue ?mid .
|
|
|
|
|
|
|
+ ?entity atlas:hasCanonicalType ?type .
|
|
|
}}
|
|
}}
|
|
|
|
|
+
|
|
|
|
|
+ ?entity atlas:hasIdentifier ?identifier .
|
|
|
|
|
+ ?identifier atlas:identifierValue ?mid ;
|
|
|
|
|
+ atlas:identifierType atlas:Mid .
|
|
|
}}
|
|
}}
|
|
|
- FILTER(LCASE(?label) = \"{esc}\")
|
|
|
|
|
|
|
+ FILTER(LCASE(STR(?label)) = LCASE("{esc}"))
|
|
|
}}
|
|
}}
|
|
|
LIMIT 1
|
|
LIMIT 1
|
|
|
"""
|
|
"""
|
|
@@ -122,11 +128,22 @@ LIMIT 1
|
|
|
def _entity_from_binding(binding: dict) -> AtlasEntity:
|
|
def _entity_from_binding(binding: dict) -> AtlasEntity:
|
|
|
label = binding.get("label", {}).get("value", "")
|
|
label = binding.get("label", {}).get("value", "")
|
|
|
entity_uri = binding.get("entity", {}).get("value", "")
|
|
entity_uri = binding.get("entity", {}).get("value", "")
|
|
|
|
|
+ # ?type is expected to be a class node like atlas:Person
|
|
|
entity_type = binding.get("type", {}).get("value", "unknown")
|
|
entity_type = binding.get("type", {}).get("value", "unknown")
|
|
|
|
|
+ if entity_type.startswith(PREFIX_ATLAS):
|
|
|
|
|
+ entity_type = entity_type.split("#", 1)[-1]
|
|
|
|
|
+ if entity_type.startswith("http://world.eu.org/atlas_ontology#"):
|
|
|
|
|
+ entity_type = entity_type.split("#", 1)[-1]
|
|
|
mid = binding.get("mid", {}).get("value")
|
|
mid = binding.get("mid", {}).get("value")
|
|
|
identifiers = []
|
|
identifiers = []
|
|
|
if mid:
|
|
if mid:
|
|
|
identifiers.append(AtlasIdentifier(value=mid, source="virtuoso", identifier_type="mid"))
|
|
identifiers.append(AtlasIdentifier(value=mid, source="virtuoso", identifier_type="mid"))
|
|
|
|
|
+
|
|
|
|
|
+ desc = binding.get("desc", {}).get("value")
|
|
|
|
|
+ raw_wd = binding.get("rawWd", {}).get("value")
|
|
|
|
|
+ raw_trends = binding.get("rawTrends", {}).get("value")
|
|
|
|
|
+
|
|
|
|
|
+ atlas_id = f"atlas:mid:{mid}" if mid else f"atlas:{label.strip().lower().replace(' ', '-') }"
|
|
|
provenance = [
|
|
provenance = [
|
|
|
AtlasProvenance(
|
|
AtlasProvenance(
|
|
|
source="virtuoso-cache",
|
|
source="virtuoso-cache",
|
|
@@ -135,11 +152,20 @@ def _entity_from_binding(binding: dict) -> AtlasEntity:
|
|
|
)
|
|
)
|
|
|
]
|
|
]
|
|
|
return AtlasEntity(
|
|
return AtlasEntity(
|
|
|
- atlas_id=entity_uri or f"atlas:{label.strip().lower().replace(' ', '-')}",
|
|
|
|
|
|
|
+ atlas_id=atlas_id,
|
|
|
canonical_label=label or entity_uri,
|
|
canonical_label=label or entity_uri,
|
|
|
|
|
+ canonical_description=desc,
|
|
|
entity_type=entity_type or "unknown",
|
|
entity_type=entity_type or "unknown",
|
|
|
aliases=[AtlasAlias(label=label or entity_uri)],
|
|
aliases=[AtlasAlias(label=label or entity_uri)],
|
|
|
identifiers=identifiers,
|
|
identifiers=identifiers,
|
|
|
provenance=provenance,
|
|
provenance=provenance,
|
|
|
- raw_payload={"source": "virtuoso", "binding": binding},
|
|
|
|
|
|
|
+ raw_payload={
|
|
|
|
|
+ "source": "virtuoso",
|
|
|
|
|
+ "raw": label or entity_uri,
|
|
|
|
|
+ "normalized": (label or entity_uri),
|
|
|
|
|
+ "mid": mid,
|
|
|
|
|
+ "wikidata": (json.loads(raw_wd) if raw_wd else {"status": "missing"}),
|
|
|
|
|
+ **(json.loads(raw_trends) if raw_trends else {}),
|
|
|
|
|
+ },
|
|
|
|
|
+ needs_curation=(entity_type or "unknown") == "unknown",
|
|
|
)
|
|
)
|