def test_parsing_member_list_specification(self): class Test8extra(ResponseElement): Foo = SimpleList() class Test8Result(ResponseElement): Item = MemberList(SimpleList) Extra = MemberList(Test8extra) text = b"""<Test8Response><Test8Result> <Item> <member>0</member> <member>1</member> <member>2</member> <member>3</member> </Item> <Extra> <member><Foo>4</Foo><Foo>5</Foo></member> <member></member> <member><Foo>6</Foo><Foo>7</Foo></member> </Extra> </Test8Result></Test8Response>""" obj = self.check_issue(Test8Result, text) self.assertSequenceEqual( list(map(int, obj._result.Item)), list(range(4)), ) self.assertSequenceEqual( list(map(lambda x: list(map(int, x.Foo)), obj._result.Extra)), [[4, 5], [], [6, 7]], )
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
def test_parsing_member_list_specification(self): class Test8extra(ResponseElement): Foo = SimpleList() class Test8Result(ResponseElement): Item = MemberList(SimpleList) Extra = MemberList(Test8extra) text = """<Test8Response><Test8Result> <Item> <member>0</member> <member>1</member> <member>2</member> <member>3</member> </Item> <Extra> <member><Foo>4</Foo><Foo>5</Foo></member> <member></member> <member><Foo>6</Foo><Foo>7</Foo></member> </Extra> </Test8Result></Test8Response>""" obj = self.check_issue(Test8Result, text) self.assertSequenceEqual( list(map(int, obj._result.Item)), list(range(4)), ) self.assertSequenceEqual( list(map(lambda x: list(map(int, x.Foo)), obj._result.Extra)), [[4, 5], [], [6, 7]], )
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.' 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
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 if self.MWSAuthToken: kw['MWSAuthToken'] = self.MWSAuthToken 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
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)
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)))
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)))
def test_cloudsearch_results_hits(self): """Check that documents are parsed properly from AWS""" search = SearchConnection(endpoint=HOSTNAME) results = search.search(q='Test') hits = list(map(lambda x: x['id'], results.docs)) # This relies on the default response which is fed into HTTPretty self.assertEqual( hits, ["12341", "12342", "12343", "12344", "12345", "12346", "12347"])
def decorator(func): action = "".join(api or map(str.capitalize, func.__name__.split("_"))) response = ResponseFactory(action) if hasattr(boto.fps.response, action + "Response"): response = getattr(boto.fps.response, action + "Response") def wrapper(self, *args, **kw): return func(self, action, response, *args, **kw) wrapper.action, wrapper.response = action, response wrapper.__doc__ = "FPS {0} API call\n{1}".format(action, func.__doc__) return wrapper
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
def decorator(func): action = ''.join(api or map(str.capitalize, func.__name__.split('_'))) response = ResponseFactory(action) if hasattr(boto.fps.response, action + 'Response'): response = getattr(boto.fps.response, action + 'Response') def wrapper(self, *args, **kw): return func(self, action, response, *args, **kw) wrapper.action, wrapper.response = action, response wrapper.__doc__ = "FPS {0} API call\n{1}".format(action, func.__doc__) return wrapper
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.' 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
def test_parsing_element_lists(self): class Test1Result(ResponseElement): Item = ElementList() text = """<Test1Response><Test1Result> <Item><Foo>Bar</Foo></Item> <Item><Zip>Bif</Zip></Item> <Item><Foo>Baz</Foo> <Zam>Zoo</Zam></Item> </Test1Result></Test1Response>""" obj = self.check_issue(Test1Result, text) self.assertTrue(len(obj._result.Item) == 3) elements = lambda x: getattr(x, 'Foo', getattr(x, 'Zip', '?')) elements = list(map(elements, obj._result.Item)) self.assertSequenceEqual(elements, ['Bar', 'Bif', 'Baz'])
def test_parsing_element_lists(self): class Test1Result(ResponseElement): Item = ElementList() text = b"""<Test1Response><Test1Result> <Item><Foo>Bar</Foo></Item> <Item><Zip>Bif</Zip></Item> <Item><Foo>Baz</Foo> <Zam>Zoo</Zam></Item> </Test1Result></Test1Response>""" obj = self.check_issue(Test1Result, text) self.assertTrue(len(obj._result.Item) == 3) elements = lambda x: getattr(x, 'Foo', getattr(x, 'Zip', '?')) elements = list(map(elements, obj._result.Item)) self.assertSequenceEqual(elements, ['Bar', 'Bif', 'Baz'])
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)
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)
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)
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)
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': val = {dynamodb_type: val.encode()} elif dynamodb_type == 'BS': val = {dynamodb_type: [n.encode() for n in val]} return val
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
def _decode_ns(self, attr): return set(map(self._decode_n, attr))
def _decode_ss(self, attr): return set(map(self._decode_s, attr))
def _decode_bs(self, attr): return set(map(self._decode_b, attr))
def _encode_ns(self, attr): return list(map(self._encode_n, attr))
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)))
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))