Coverage for python/lsst/verify/blob.py: 32%
62 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-27 02:05 -0700
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-27 02:05 -0700
1# This file is part of verify.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21__all__ = ['Blob']
23import uuid
25from .jsonmixin import JsonSerializationMixin
26from .datum import Datum
29class Blob(JsonSerializationMixin):
30 r"""Blob is a flexible container of data, as `lsst.verify.Datum` \s, that
31 are serializable to JSON.
33 Parameters
34 ----------
35 name : `str`
36 Name of this type of blob. Blobs from one pipeline Job execution to
37 another that share the same name generally share the same schema of
38 `lsst.verify.Datum`\ s.
39 datums : `dict` of `lsst.verify.Datum`-types, optional
40 Keys are names of datums. Values are `~lsst.verify.Datum`\ -types.
41 Each `~lsst.verify.Datum` can be later retrived from the Blob instance
42 by key.
43 """
45 def __init__(self, name, **datums):
46 # Internal read-only instance ID, access with the name attribute
47 self._id = uuid.uuid4().hex
49 if not isinstance(name, str):
50 message = 'Blob name {0!r} must be a string'.format(name)
51 raise TypeError(message)
52 self._name = name
54 # Internal Datum dictionary
55 self._datums = {}
57 for key, datum in datums.items():
58 self[key] = datum
60 @property
61 def name(self):
62 """Name of this blob (`str`)."""
63 return self._name
65 @property
66 def identifier(self):
67 """Unique UUID4-based identifier for this blob (`str`)."""
68 return self._id
70 @classmethod
71 def deserialize(cls, identifier=None, name=None, data=None):
72 """Deserialize fields from a blob JSON object into a `Blob` instance.
74 Parameters
75 ----------
76 identifier : `str`
77 Blob identifier.
78 name : `str`
79 Name of the blob type.
80 data : `dict`
81 Dictionary of named ``name: datum object`` key-value pairs.
83 Returns
84 -------
85 blob : `Blob`
86 The `Blob` instance deserialied from a blob JSON object.
88 Examples
89 --------
90 This class method is designed to roundtrip JSON objects created a
91 Blob instance. For example:
93 >>> import astropy.units as u
94 >>> blob = Blob('demo')
95 >>> blob['a_mag'] = Datum(28 * u.mag, label='i')
96 >>> json_data = blob.json
97 >>> new_blob = Blob.deserialize(**json_data)
98 """
99 datums = {}
100 if data is not None:
101 for datum_key, datum_doc in data.items():
102 datum = Datum.deserialize(**datum_doc)
103 datums[datum_key] = datum
104 instance = cls(name, **datums)
105 instance._id = identifier
106 return instance
108 @property
109 def json(self):
110 """Job data as a JSON-serializable `dict`."""
111 json_doc = JsonSerializationMixin.jsonify_dict({
112 'identifier': self.identifier,
113 'name': self.name,
114 'data': self._datums})
115 return json_doc
117 def __setitem__(self, key, value):
118 if not isinstance(key, str):
119 message = 'Key {0!r} is not a string.'.format(key)
120 raise KeyError(message)
122 if not isinstance(value, Datum):
123 message = '{0} is not a Datum-type'.format(value)
124 raise TypeError(message)
126 self._datums[key] = value
128 def __getitem__(self, key):
129 return self._datums[key]
131 def __delitem__(self, key):
132 del self._datums[key]
134 def __len__(self):
135 return len(self._datums)
137 def __contains__(self, key):
138 return key in self._datums
140 def __iter__(self):
141 for key in self._datums:
142 yield key
144 def __eq__(self, other):
145 return (self.identifier == other.identifier) \
146 and (self.name == other.name) \
147 and (self._datums == other._datums)
149 def __ne__(self, other):
150 return not self.__eq__(other)
152 def keys(self):
153 """Get keys of blob items.
155 Returns
156 -------
157 keys : sequence of `str`
158 Sequence of keys to items in the Blob.
159 """
160 return self._datums.keys()
162 def items(self):
163 """Get pairs of keys and values in the Blob.
165 Yields
166 ------
167 keyval : tuple
168 Tuple of:
170 - key (`str`)
171 - datum (`lsst.verify.Datum`)
172 """
173 for key, val in self._datums.items():
174 yield key, val