Source code for yggdrasil.metaschema.datatypes.JSONObjectMetaschemaType
import numpy as np
import pandas as pd
from collections import OrderedDict
from yggdrasil.metaschema.datatypes.ContainerMetaschemaType import (
ContainerMetaschemaType)
[docs]class JSONObjectMetaschemaType(ContainerMetaschemaType):
r"""Type associated with a map.
Developer Notes:
Support for dynamic objects in C/C++ is still under development.
"""
name = 'object'
description = 'A container mapping between keys and values.'
properties = ['properties']
metadata_properties = ['properties']
extract_properties = ['properties']
python_types = (dict, )
_replaces_existing = True
_container_type = dict
_json_type = 'object'
_json_property = 'properties'
_empty_msg = {}
[docs] @classmethod
def coerce_type(cls, obj, typedef=None, key_order=None, **kwargs):
r"""Coerce objects of specific types to match the data type.
Args:
obj (object): Object to be coerced.
typedef (dict, optional): Type defintion that object should be
coerced to. Defaults to None.
key_order (list, optional): Order or keys correpsonding to elements in
a provided list or tuple. Defaults to None.
**kwargs: Additional keyword arguments are metadata entries that may
aid in coercing the type.
Returns:
object: Coerced object.
Raises:
RuntimeError: If obj is a list or tuple, but key_order is not provided.
"""
from yggdrasil.serialize import pandas2dict, numpy2dict, list2dict
if isinstance(obj, pd.DataFrame):
obj = pandas2dict(obj)
elif isinstance(obj, np.ndarray) and (len(obj.dtype) > 0):
obj = numpy2dict(obj)
elif isinstance(obj, (list, tuple)) and (key_order is not None):
obj = list2dict(obj, names=key_order)
return super(JSONObjectMetaschemaType, cls).coerce_type(
obj, typedef=typedef, **kwargs)
@classmethod
def _iterate(cls, container):
r"""Iterate over the contents of the container. Each element returned
should be a tuple including an index and a value.
Args:
container (obj): Object to be iterated over.
Returns:
iterator: Iterator over elements in the container.
"""
for k, v in container.items():
yield (k, v)
@classmethod
def _assign(cls, container, index, value):
r"""Assign an element in the container to the specified value.
Args:
container (obj): Object that element will be assigned to.
index (obj): Index in the container object where element will be
assigned.
value (obj): Value that will be assigned to the element in the
container object.
"""
container[index] = value
@classmethod
def _has_element(cls, container, index):
r"""Check to see if an index is in the container.
Args:
container (obj): Object that should be checked for index.
index (obj): Index that should be checked for.
Returns:
bool: True if the index is in the container.
"""
return (index in container)
@classmethod
def _encode_data_alias(cls, obj, typedef, func_encode, container_type=None):
r"""Encode an object's data using a sepcified function.
Args:
obj (object): Object to encode.
typedef (dict): Type definition that should be used to encode the
object.
func_encode (callable): Function that should be used to encode
elements in the container. Defaults to encode_data.
container_type (type, optional): Type that should be used for the
output container. Defaults to cls._container_type.
Returns:
string: Encoded object.
"""
if (container_type is None) and isinstance(obj, OrderedDict):
container_type = OrderedDict
return super(JSONObjectMetaschemaType, cls)._encode_data_alias(
obj, typedef, func_encode, container_type=container_type)
[docs] @classmethod
def get_test_data(cls, typedef=None):
r"""object: Test data."""
if (typedef is None) and (cls.name == 'object'):
typedef = {
'type': 'object',
'properties': {
'a': {'type': 'float',
'precision': 32,
'units': ''},
'b': {'type': 'bytes',
'precision': 40,
'units': ''},
'c': {'type': 'unicode',
'precision': 40,
'units': ''},
'd': {'type': 'object',
'properties': {'nested': {'type': 'int',
'precision': 64,
'units': ''}}},
'e': {'type': 'array',
'items': [{'type': 'complex',
'precision': 128,
'units': ''},
{'type': 'uint',
'precision': 8,
'units': ''}]}}}
return super(JSONObjectMetaschemaType, cls).get_test_data(typedef)