Source code for owmeta_movement
'''
This example uses the WCON JSON-schema to build a DataSource type and then creates a new
DataSource with the values from an instance conforming to the schema
'''
from pkg_resources import resource_stream
import json
import importlib
from owmeta_core.collections import Seq
from owmeta_core.context import ClassContext
from owmeta_core import BASE_CONTEXT
from owmeta_core.json_schema import (DataObjectTypeCreator,
DataObjectCreator)
from pow_zodb.ZODB import register_id_series
from rdflib.namespace import Namespace
from rdflib.term import Literal
BASE_SCHEMA_URL = 'http://schema.openworm.org/2020/07/sci/bio/movement'
BASE_DATA_URL = 'http://data.openworm.org/sci/bio/movement'
CONTEXT = ClassContext(imported=(BASE_CONTEXT,),
ident=BASE_SCHEMA_URL,
base_namespace=BASE_SCHEMA_URL + '#')
class WormTracksTypeCreator(DataObjectTypeCreator):
def __init__(self, name, schema, **kwargs):
super().__init__(name,
schema,
module=__name__,
context=CONTEXT,
**kwargs)
def create_type(self, path, schema):
cdict = self.cdict.setdefault(path, {})
cdict['base_namespace'] = Namespace(BASE_SCHEMA_URL + '/')
cdict['base_data_namespace'] = Namespace(BASE_DATA_URL + '/')
res = super().create_type(path, schema)
mod = importlib.import_module(__name__)
setattr(mod, res.__name__, res)
res.register_on_module(mod)
return res
[docs]class WCONWormTracksCreator(DataObjectCreator):
'''
Creates `WormTracks` from WCON deserialized to Python objects
'''
# XXX: This class might end up being a WCONDataObjectCreator instead... we massage the
# WCON into the right format in the DataTranslator for each type, but the mapping from
# well-formed WCON to WormTracks can be shared.
def begin_sequence(self, schema):
path = self.path_stack
if len(path) == 1 and path[0] == 'data':
return Seq.contextualize(self.context)(ident=self.gen_ident())
return super().begin_sequence(schema)
def add_to_sequence(self, schema, sequence, idx, item):
path = self.path_stack
if isinstance(sequence, Seq) and len(path) == 2 and path[0] == 'data':
if item is None:
return sequence
# rdf:Seq is one-indexed
sequence[idx + 1] = item
return sequence
return super().add_to_sequence(schema, sequence, idx, item)
def assign(self, obj, key, val):
path = self.path_stack
if len(path) == 2 and path[0] == 'data' and isinstance(val, (dict, list)):
val = DataLiteral(val)
super().assign(obj, key, val)
_wcon_schema = resource_stream('owmeta_movement', 'wcon_schema_2017_06.json')
with _wcon_schema:
_schema = json.load(_wcon_schema)
# If we later get another version of the schema or change how this data source is
# implemented, we can add on here. The dates are for the owmeta_movement schema version
# rather than the WCON schema version
WCON_SCHEMA_2020_07 = WormTracksTypeCreator('WormTracks', _schema).annotate()
del _wcon_schema
del _schema
WormTracks = WormTracksTypeCreator.retrieve_type(WCON_SCHEMA_2020_07)
WCONWormTracksCreator_2020_07 = WCONWormTracksCreator(WCON_SCHEMA_2020_07)
DATA_LITERAL_SERIES = __name__ + '.DataLiteral'
register_id_series(DATA_LITERAL_SERIES)
class DataLiteral(Literal):
zodb_id_series = DATA_LITERAL_SERIES