Skip to content

Commit

Permalink
Pass through SSSOM JSON-LD context when writing JSON (#479)
Browse files Browse the repository at this point in the history
Fixes #477

---------

Co-authored-by: Charles Tapley Hoyt <cthoyt@gmail.com>
  • Loading branch information
matentzn and cthoyt authored Dec 11, 2023
1 parent 91b803f commit f425604
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
8 changes: 6 additions & 2 deletions src/sssom/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,15 @@ def _get_default_converter() -> Converter:
return Converter(records)


def _load_sssom_context():
with open(SSSOM_CONTEXT) as file:
return json.load(file, strict=False)


@lru_cache(1)
def _get_built_in_prefix_map() -> Converter:
"""Get URI prefixes for built-in prefixes."""
with open(SSSOM_CONTEXT) as file:
context = json.load(file, strict=False)
context = _load_sssom_context()
prefix_map = {
prefix: uri_prefix
for prefix, uri_prefix in context["@context"].items()
Expand Down
18 changes: 17 additions & 1 deletion src/sssom/writers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import pandas as pd
import yaml
from curies import Converter
from jsonasobj2 import JsonObj
from linkml_runtime.dumpers import JSONDumper, rdflib_dumper
from linkml_runtime.utils.schemaview import SchemaView
Expand All @@ -17,6 +18,7 @@
from sssom.validators import check_all_prefixes_in_curie_map

from .constants import CURIE_MAP, SCHEMA_YAML, SSSOM_URI_PREFIX
from .context import _load_sssom_context
from .parsers import to_mapping_set_document
from .util import (
RDF_FORMATS,
Expand Down Expand Up @@ -433,10 +435,24 @@ def to_fhir_json(msdf: MappingSetDataFrame) -> Dict:
return json_obj


def _update_sssom_context_with_prefixmap(converter: Converter):
"""Prepare a JSON-LD context and dump to a string."""
context = _load_sssom_context()
for k, v in converter.bimap.items():
if k in context["@context"] and context["@context"][k] != v:
logging.info(
f"{k} namespace is already in the context, ({context['@context'][k]}, "
f"but with a different value than {v}. Overwriting!"
)
context["@context"][k] = v
return context


def to_json(msdf: MappingSetDataFrame) -> JsonObj:
"""Convert a mapping set dataframe to a JSON object."""
doc = to_mapping_set_document(msdf)
data = JSONDumper().dumps(doc.mapping_set, contexts={"@context": doc.prefix_map})
context = _update_sssom_context_with_prefixmap(doc.converter)
data = JSONDumper().dumps(doc.mapping_set, contexts=json.dumps(context))
json_obj = json.loads(data)
return json_obj

Expand Down
61 changes: 61 additions & 0 deletions tests/test_writers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,23 @@
import os
import unittest

import pandas as pd
from curies import Converter

from sssom import MappingSetDataFrame
from sssom.constants import (
CREATOR_ID,
OBJECT_ID,
OBJECT_LABEL,
PREDICATE_ID,
SEMAPV,
SUBJECT_ID,
SUBJECT_LABEL,
)
from sssom.parsers import parse_sssom_json, parse_sssom_rdf, parse_sssom_table
from sssom.writers import (
_update_sssom_context_with_prefixmap,
to_json,
write_fhir_json,
write_json,
write_ontoportal_json,
Expand Down Expand Up @@ -67,6 +82,52 @@ def test_write_sssom_json(self):
f"{path} has the wrong number of mappings.",
)

def test_write_sssom_json_context(self):
"""Test when writing to JSON, the context is correctly written as well."""
rows = [
(
"DOID:0050601",
"ADULT syndrome",
"skos:exactMatch",
"UMLS:C1863204",
"ADULT SYNDROME",
SEMAPV.ManualMappingCuration.value,
"orcid:0000-0003-4423-4370",
)
]
columns = [
SUBJECT_ID,
SUBJECT_LABEL,
PREDICATE_ID,
OBJECT_ID,
OBJECT_LABEL,
SEMAPV.ManualMappingCuration.value,
CREATOR_ID,
]
df = pd.DataFrame(rows, columns=columns)
msdf = MappingSetDataFrame(df)
msdf.clean_prefix_map()
json_object = to_json(msdf)
self.assertIn("@context", json_object)
self.assertIn("DOID", json_object["@context"])
self.assertIn("mapping_set_id", json_object["@context"])

def test_update_sssom_context_with_prefixmap(self):
"""Test when writing to JSON, the context is correctly written as well."""
records = [
{
"prefix": "SCTID",
"prefix_synonyms": ["snomed"],
"uri_prefix": "http://snomed.info/id/",
},
]
converter = Converter.from_extended_prefix_map(records)
context = _update_sssom_context_with_prefixmap(converter)
self.assertIn("@context", context)
self.assertIn("SCTID", context["@context"])
self.assertNotIn("snomed", context["@context"])
self.assertIn("mapping_set_id", context["@context"])

def test_write_sssom_fhir(self):
"""Test writing as FHIR ConceptMap JSON."""
path = os.path.join(test_out_dir, "test_write_sssom_fhir.json")
Expand Down

0 comments on commit f425604

Please sign in to comment.