Source code for lsst.verify.blob
#
# LSST Data Management System
#
# This product includes software developed by the
# LSST Project (http://www.lsst.org/).
#
# See COPYRIGHT file at the top of the source tree.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the LSST License Statement and
# the GNU General Public License along with this program. If not,
# see <https://www.lsstcorp.org/LegalNotices/>.
#
from __future__ import print_function, division
__all__ = ['Blob']
from past.builtins import basestring
import uuid
from .jsonmixin import JsonSerializationMixin
from .datum import Datum
[docs]class Blob(JsonSerializationMixin):
"""Blob is a flexible container of data, as `lsst.verify.Datum` \s, that
are serializable to JSON.
Parameters
----------
name : `str`
Name of this type of blob. Blobs from one pipeline Job execution to
another that share the same name generally share the same schema of
`lsst.verify.Datum`\ s.
datums : `dict` of `lsst.verify.Datum`-types, optional
Keys are names of datums. Values are `~lsst.verify.Datum`\ -types.
Each `~lsst.verify.Datum` can be later retrived from the Blob instance
by key.
"""
def __init__(self, name, **datums):
# Internal read-only instance ID, access with the name attribute
self._id = uuid.uuid4().hex
if not isinstance(name, basestring):
message = 'Blob name {0!r} must be a string'.format(name)
raise TypeError(message)
self._name = name
# Internal Datum dictionary
self._datums = {}
for key, datum in datums.items():
self[key] = datum
@property
def name(self):
"""Name of this blob (`str`)."""
return self._name
@property
def identifier(self):
"""Unique UUID4-based identifier for this blob (`str`)."""
return self._id
@classmethod
[docs] def deserialize(cls, identifier=None, name=None, data=None):
"""Deserialize fields from a blob JSON object into a `Blob` instance.
Parameters
----------
identifier : `str`
Blob identifier.
name : `str`
Name of the blob type.
data : `dict`
Dictionary of named ``name: datum object`` key-value pairs.
Returns
-------
blob : `Blob`
The `Blob` instance deserialied from a blob JSON object.
Example
-------
This class method is designed to roundtrip JSON objects created a
Blob instance. For example:
>>> import astropy.units as u
>>> blob = Blob('demo')
>>> blob['a_mag'] = Datum(28 * u.mag, label='i')
>>> json_data = blob.json
>>> new_blob = Blob.deserialize(**json_data)
"""
datums = {}
if data is not None:
for datum_key, datum_doc in data.items():
datum = Datum.deserialize(**datum_doc)
datums[datum_key] = datum
instance = cls(name, **datums)
instance._id = identifier
return instance
@property
def json(self):
"""Job data as a JSON-serializable `dict`."""
json_doc = JsonSerializationMixin.jsonify_dict({
'identifier': self.identifier,
'name': self.name,
'data': self._datums})
return json_doc
def __setitem__(self, key, value):
if not isinstance(key, basestring):
message = 'Key {0!r} is not a string.'.format(key)
raise KeyError(message)
if not isinstance(value, Datum):
message = '{0} is not a Datum-type'.format(value)
raise TypeError(message)
self._datums[key] = value
def __getitem__(self, key):
return self._datums[key]
def __delitem__(self, key):
del self._datums[key]
def __len__(self):
return len(self._datums)
def __contains__(self, key):
return key in self._datums
def __iter__(self):
for key in self._datums:
yield key
def __eq__(self, other):
return (self.identifier == other.identifier) \
and (self.name == other.name) \
and (self._datums == other._datums)
def __ne__(self, other):
return not self.__eq__(other)
[docs] def keys(self):
"""Get keys of blob items.
Returns
-------
keys : sequence of `str`
Sequence of keys to items in the Blob.
"""
return self._datums.keys()
[docs] def items(self):
"""Get pairs of keys and values in the Blob.
Yields
------
keyval : tuple
Tuple of:
- key (`str`)
- datum (`lsst.verify.Datum`)
"""
for key, val in self._datums.items():
yield key, val