Source code for pilosa.response

# Copyright 2017 Pilosa Corp.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#

from .exceptions import PilosaError
from .internal import public_pb2 as internal


__all__ = ("BitmapResult", "CountResultItem", "QueryResult", "ColumnItem", "QueryResponse")


[docs]class BitmapResult: """Represents a result from ``Bitmap``, ``Union``, ``Intersect``, ``Difference`` and ``Range`` PQL calls. * See `Query Language <https://www.pilosa.com/docs/query-language/>`_ """ def __init__(self, bits=None, attributes=None): self.bits = bits or [] self.attributes = attributes or {} @classmethod
[docs] def from_internal(cls, obj): return cls(list(obj.Bits), _convert_protobuf_attrs_to_dict(obj.Attrs))
[docs]class CountResultItem: """Represents a result from ``TopN`` call. * See `Query Language <https://www.pilosa.com/docs/query-language/>`_ """ def __init__(self, id, count): self.id = id self.count = count
[docs]class QueryResult: """Represents one of the results in the response. * See `Query Language <https://www.pilosa.com/docs/query-language/>`_ """ def __init__(self, bitmap=None, count_items=None, count=0, sum=0): self.bitmap = bitmap or BitmapResult() self.count_items = count_items or [] self.count = count self.sum = sum @classmethod
[docs] def from_internal(cls, obj): count_items = [] for pair in obj.Pairs: count_items.append(CountResultItem(pair.Key, pair.Count)) count = obj.N if obj.N > 0 else obj.SumCount.Count return cls(BitmapResult.from_internal(obj.Bitmap), count_items, count, obj.SumCount.Sum)
[docs]class ColumnItem: """Contains data about a column. Column data is returned from ``QueryResponse.getColumns()`` method. They are only returned if ``Client.query`` was called with ``columns=True``. """ def __init__(self, id, attributes): self.id = id self.attributes = attributes @classmethod def _from_internal(cls, obj): return cls(obj.ID, _convert_protobuf_attrs_to_dict(obj.Attrs))
[docs]class QueryResponse(object): """Represents the response from a Pilosa query. * See `Query Language <https://www.pilosa.com/docs/query-language/>`_ """ def __init__(self, results=None, columns=None, error_message=""): self.results = results or [] self.columns = columns or [] self.error_message = error_message @classmethod def _from_protobuf(cls, bin): response = internal.QueryResponse() response.ParseFromString(bin) results = [QueryResult.from_internal(r) for r in response.Results] columns = [ColumnItem._from_internal(p) for p in response.ColumnAttrSets] error_message = response.Err return cls(results, columns, error_message) @property def result(self): return self.results[0] if self.results else None @property def column(self): return self.columns[0] if self.columns else None
def _convert_protobuf_attrs_to_dict(attrs): protobuf_attrs_to_dict = [ None, lambda a: a.StringValue, lambda a: a.IntValue, lambda a: a.BoolValue, lambda a: a.FloatValue, ] d = {} attr = None # to get the attr with invalid type try: for attr in attrs: value = protobuf_attrs_to_dict[attr.Type](attr) d[attr.Key] = value except (IndexError, TypeError): raise PilosaError("Invalid protobuf attribute type: %s" % attr.Type) return d