예제 #1
0
def get_dynamodb_type(val, use_boolean=True):
    """
    Take a scalar Python value and return a string representing
    the corresponding Amazon DynamoDB type.  If the value passed in is
    not a supported type, raise a TypeError.
    """
    dynamodb_type = None
    if val is None:
        dynamodb_type = 'NULL'
    elif is_num(val):
        if isinstance(val, bool) and use_boolean:
            dynamodb_type = 'BOOL'
        else:
            dynamodb_type = 'N'
    elif is_str(val):
        dynamodb_type = 'S'
    elif isinstance(val, (set, frozenset)):
        if False not in map(is_num, val):
            dynamodb_type = 'NS'
        elif False not in map(is_str, val):
            dynamodb_type = 'SS'
        elif False not in map(is_binary, val):
            dynamodb_type = 'BS'
    elif is_binary(val):
        dynamodb_type = 'B'
    elif isinstance(val, Mapping):
        dynamodb_type = 'M'
    elif isinstance(val, list):
        dynamodb_type = 'L'
    if dynamodb_type is None:
        msg = 'Unsupported type "%s" for value "%s"' % (type(val), val)
        raise TypeError(msg)
    return dynamodb_type
예제 #2
0
    def build_put_params(self,
                         params,
                         name,
                         value=None,
                         timestamp=None,
                         unit=None,
                         dimensions=None,
                         statistics=None):
        args = (name, value, unit, dimensions, statistics, timestamp)
        length = max(map(lambda a: len(a) if isinstance(a, list) else 1, args))

        def aslist(a):
            if isinstance(a, list):
                if len(a) != length:
                    raise Exception(
                        'Must specify equal number of elements; expected %d.' %
                        length)
                return a
            return [a] * length

        for index, (n, v, u, d, s, t) in enumerate(zip(*map(aslist, args))):
            metric_data = {'MetricName': n}

            if timestamp:
                metric_data['Timestamp'] = t.isoformat()

            if unit:
                metric_data['Unit'] = u

            if dimensions:
                self.build_dimension_param(d, metric_data)

            if statistics:
                metric_data['StatisticValues.Maximum'] = s['maximum']
                metric_data['StatisticValues.Minimum'] = s['minimum']
                metric_data['StatisticValues.SampleCount'] = s['samplecount']
                metric_data['StatisticValues.Sum'] = s['sum']
                if value is not None:
                    msg = 'You supplied a value and statistics for a ' + \
                          'metric.Posting statistics and not value.'
                    fcu_boto.log.warn(msg)
            elif value is not None:
                metric_data['Value'] = v
            else:
                raise Exception('Must specify a value or statistics to put.')

            for key, val in six.iteritems(metric_data):
                params['MetricData.member.%d.%s' % (index + 1, key)] = val
예제 #3
0
 def get_service_status(self, **kw):
     """Instruct the user on how to get service status.
     """
     sections = ', '.join(map(str.lower, api_version_path.keys()))
     message = "Use {0}.get_(section)_service_status(), " \
               "where (section) is one of the following: " \
               "{1}".format(self.__class__.__name__, sections)
     raise AttributeError(message)
예제 #4
0
 def __repr__(self):
     render = lambda pair: '{0!s}: {1!r}'.format(*pair)
     do_show = lambda pair: not pair[0].startswith('_')
     attrs = filter(do_show, self.__dict__.items())
     name = self.__class__.__name__
     if name.startswith('JIT_'):
         name = '^{0}^'.format(self._name or '')
     return '{0}{1!r}({2})'.format(name, self.copy(),
                                   ', '.join(map(render, attrs)))
예제 #5
0
def item_object_hook(dct):
    """
    A custom object hook for use when decoding JSON item bodys.
    This hook will transform Amazon DynamoDB JSON responses to something
    that maps directly to native Python types.
    """
    if len(dct.keys()) > 1:
        return dct
    if 'S' in dct:
        return dct['S']
    if 'N' in dct:
        return convert_num(dct['N'])
    if 'SS' in dct:
        return set(dct['SS'])
    if 'NS' in dct:
        return set(map(convert_num, dct['NS']))
    if 'B' in dct:
        return convert_binary(dct['B'])
    if 'BS' in dct:
        return set(map(convert_binary, dct['BS']))
    return dct
예제 #6
0
    def decode_time(self, value):
        """ converts strings in the form of HH:MM:SS.mmmmmm
            (created by datetime.time.isoformat()) to
            datetime.time objects.

            Timzone-aware strings ("HH:MM:SS.mmmmmm+HH:MM") won't
            be handled right now and will raise TimeDecodeError.
        """
        if '-' in value or '+' in value:
            # TODO: Handle tzinfo
            raise TimeDecodeError("Can't handle timezone aware objects: %r" %
                                  value)
        tmp = value.split('.')
        arg = map(int, tmp[0].split(':'))
        if len(tmp) == 2:
            arg.append(int(tmp[1]))
        return time(*arg)
예제 #7
0
    def __init__(self, **attrs):
        self.rid = attrs['status']['rid']
        self.time_ms = attrs['status']['time-ms']
        self.hits = attrs['hits']['found']
        self.docs = attrs['hits']['hit']
        self.start = attrs['hits']['start']
        self.query = attrs['query']
        self.search_service = attrs['search_service']

        self.facets = {}
        if 'facets' in attrs:
            for (facet, values) in attrs['facets'].items():
                if 'buckets' in values:
                    self.facets[facet] = dict(
                        (k, v)
                        for (k, v) in map(lambda x: (x['value'], x['count']),
                                          values.get('buckets', [])))

        self.num_pages_needed = ceil(self.hits / self.query.real_size)
예제 #8
0
def dynamize_value(val):
    """
    Take a scalar Python value and return a dict consisting
    of the Amazon DynamoDB type specification and the value that
    needs to be sent to Amazon DynamoDB.  If the type of the value
    is not supported, raise a TypeError
    """
    dynamodb_type = get_dynamodb_type(val)
    if dynamodb_type == 'N':
        val = {dynamodb_type: serialize_num(val)}
    elif dynamodb_type == 'S':
        val = {dynamodb_type: val}
    elif dynamodb_type == 'NS':
        val = {dynamodb_type: list(map(serialize_num, val))}
    elif dynamodb_type == 'SS':
        val = {dynamodb_type: [n for n in val]}
    elif dynamodb_type == 'B':
        if isinstance(val, bytes):
            val = Binary(val)
        val = {dynamodb_type: val.encode()}
    elif dynamodb_type == 'BS':
        val = {dynamodb_type: [n.encode() for n in val]}
    return val
예제 #9
0
    def __init__(self, **attrs):
        self.rid = attrs['info']['rid']
        # self.doc_coverage_pct = attrs['info']['doc-coverage-pct']
        self.cpu_time_ms = attrs['info']['cpu-time-ms']
        self.time_ms = attrs['info']['time-ms']
        self.hits = attrs['hits']['found']
        self.docs = attrs['hits']['hit']
        self.start = attrs['hits']['start']
        self.rank = attrs['rank']
        self.match_expression = attrs['match-expr']
        self.query = attrs['query']
        self.search_service = attrs['search_service']

        self.facets = {}
        if 'facets' in attrs:
            for (facet, values) in attrs['facets'].items():
                if 'constraints' in values:
                    self.facets[facet] = dict(
                        (k, v)
                        for (k, v) in map(lambda x: (x['value'], x['count']),
                                          values['constraints']))

        self.num_pages_needed = ceil(self.hits / self.query.real_size)
예제 #10
0
    def decorator(func, quota=int(quota), restore=float(restore)):
        version, accesskey, path = api_version_path[section]
        action = ''.join(api or map(str.capitalize, func.__name__.split('_')))

        def wrapper(self, *args, **kw):
            kw.setdefault(accesskey, getattr(self, accesskey, None))
            if kw[accesskey] is None:
                message = "{0} requires {1} argument. Set the " \
                          "MWSConnection.{2} attribute?" \
                          "".format(action, accesskey, accesskey)
                raise KeyError(message)
            kw['Action'] = action
            kw['Version'] = version
            response = self._response_factory(action, connection=self)
            request = dict(path=path, quota=quota, restore=restore)
            return func(self, request, response, *args, **kw)

        for attr in decorated_attrs:
            setattr(wrapper, attr, locals().get(attr))
        wrapper.__doc__ = "MWS {0}/{1} API call; quota={2} restore={3:.2f}\n" \
                          "{4}".format(action, version, quota, restore,
                                       func.__doc__)
        api_call_map[action] = func.__name__
        return wrapper
예제 #11
0
 def __repr__(self):
     values = [getattr(self, key, None) for key in self._dimensions]
     values = filter(None, values)
     return 'x'.join(map('{0.Value:0.2f}{0[Units]}'.format, values))
예제 #12
0
 def _decode_ns(self, attr):
     return set(map(self._decode_n, attr))
예제 #13
0
 def _decode_bs(self, attr):
     return set(map(self._decode_b, attr))
예제 #14
0
 def _decode_ss(self, attr):
     return set(map(self._decode_s, attr))
예제 #15
0
 def _encode_ns(self, attr):
     return list(map(self._encode_n, attr))
예제 #16
0
 def __repr__(self):
     render = lambda pair: '{!s}: {!r}'.format(*pair)
     do_show = lambda pair: not pair[0].startswith('_')
     attrs = filter(do_show, self.__dict__.items())
     return '{0}({1})'.format(self.__class__.__name__,
                              ', '.join(map(render, attrs)))