From: Diane Trout Date: Fri, 17 Jan 2014 00:06:50 +0000 (-0800) Subject: Add functions to create a json-ld context and add namespaces to a context X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=htsworkflow.git;a=commitdiff_plain;h=ba2568a6f5d04544a9d89261f57d9a13e43bdd95 Add functions to create a json-ld context and add namespaces to a context Having smaller functions like this makes it easier to test. --- diff --git a/htsworkflow/submission/encoded.py b/htsworkflow/submission/encoded.py index 8eec0c0..5072713 100644 --- a/htsworkflow/submission/encoded.py +++ b/htsworkflow/submission/encoded.py @@ -64,7 +64,7 @@ ENCODED_CONTEXT = { } #FIXME: this needs to be initialized from rdfns -_encoded_namespaces = { +ENCODED_NAMESPACES = { # JSON-LD lets you define namespaces so you can used the shorted url syntax. # (instead of http://www.w3.org/2000/01/rdf-schema#label you can do # rdfs:label) @@ -84,17 +84,17 @@ _encoded_namespaces = { # SO: available from http://www.berkeleybop.org/ontologies/so.owl } -ENCODED_CONTEXT[None].update(_encoded_namespaces) + ENCODED_SCHEMA_ROOT='/profiles/' class ENCODED: '''Programatic access encoded, the software powering ENCODE3's submit site. ''' - def __init__(self, server, context=None): + def __init__(self, server, contexts=None): self.server = server self.username = None self.password = None - self.context = context if context else ENCODED_CONTEXT + self.contexts = contexts if contexts else ENCODED_CONTEXT self.schemas = {} def get_auth(self): @@ -136,24 +136,41 @@ class ENCODED: if isinstance(obj, collections.Sequence): # how should I update lists? for v in obj: - self.add_jsonld_child_context(v, contexts) + self.add_jsonld_child_context(v, default_base) return if isinstance(obj, collections.Mapping): for v in obj.values(): - self.add_jsonld_child_context(v, contexts) + self.add_jsonld_child_context(v, default_base) # we have an object. attach a context to it. if self._is_encoded_object(obj): - default_base = contexts[None]['@base'] - context = {'@base': urljoin(default_base, obj['@id']), - '@vocab': self.get_schema_url(obj)} - for t in obj['@type']: - if t in contexts: - context.update(contexts[t]) + context = self.create_jsonld_context(obj, default_base) if len(context) > 0: obj.setdefault('@context', {}).update(context) + def add_jsonld_namespaces(self, context): + '''Add shortcut namespaces to a context + + Only needs to be run on the top-most context + ''' + context.update(ENCODED_NAMESPACES) + + def create_jsonld_context(self, obj, default_base): + '''Synthesize the context for a encoded type + + self.contexts[None] = default context attributes added to any type + self.contexts[type] = context attributes for this type. + ''' + context = {'@base': urljoin(default_base, obj['@id']), + '@vocab': self.get_schema_url(obj)} + # add in defaults + context.update(self.contexts[None]) + for t in obj['@type']: + if t in self.contexts: + context.update(self.contexts[t]) + return context + def get_json(self, obj_id, **kwargs): '''GET an ENCODE object as JSON and return as dict diff --git a/htsworkflow/submission/test/test_encoded.py b/htsworkflow/submission/test/test_encoded.py index e5b2707..5e0e69b 100644 --- a/htsworkflow/submission/test/test_encoded.py +++ b/htsworkflow/submission/test/test_encoded.py @@ -3,7 +3,10 @@ import os from pprint import pprint from unittest2 import TestCase, TestSuite, defaultTestLoader, skip -from htsworkflow.submission.encoded import ENCODED +from htsworkflow.submission.encoded import (ENCODED, + ENCODED_CONTEXT, + ENCODED_NAMESPACES +) class TestEncoded(TestCase): def test_prepare_url(self): @@ -56,6 +59,20 @@ class TestEncoded(TestCase): encode.validate(obj) self.assertTrue('@id' in obj) + def test_create_context(self): + linked_id = {'@type': '@id'} + library = { '@id': '/libraries/1234', '@type': ['library', 'item'] } + + encode = ENCODED('test.encodedcc.org') + url = encode.prepare_url(library['@id']) + context = encode.create_jsonld_context(library, url) + self.assertEqual(context['award'], linked_id ) + self._verify_context(context, 'library') + # namespaces not added yet. + self.assertRaises(AssertionError, self._verify_namespaces, context) + encode.add_jsonld_namespaces(context) + self._verify_namespaces(context) + def test_add_context(self): """Checking to make sure nested @base and @vocab urls are set correctly """ @@ -97,7 +114,23 @@ class TestEncoded(TestCase): self.assertEqual(obj['biosample']['@context']['@base'], bio_base) self.assertEqual(obj['@context']['@vocab'], schema_url) + self._verify_context(obj['@context'], 'library') + self._verify_namespaces(obj['@context']) + self._verify_context(obj['biosample']['@context'], 'biosample') + self.assertEqual(obj['@context']['rdf'], 'http://www.w3.org/1999/02/22-rdf-syntax-ns#') + self.assertEqual(obj['@context']['OBO'], 'http://purl.obolibrary.org/obo/') + + + def _verify_context(self, context, obj_type): + for context_key in [None, obj_type]: + for k in ENCODED_CONTEXT[context_key]: + self.assertIn(k, context) + self.assertEqual(ENCODED_CONTEXT[context_key][k], context[k]) + def _verify_namespaces(self, context): + for k in ENCODED_NAMESPACES: + self.assertIn(k, context) + self.assertEqual(ENCODED_NAMESPACES[k], context[k]) def suite(): suite = TestSuite()