def call(self, command, **kwargs):
        for hook in self._hooks['precall']:
            hook(self, command, kwargs)
        op = getattr(self.client, command)
        attempt = 0
        while True:
            try:
                data = op(**kwargs)
                break
            except ClientError as e:
                exc = translate_exception(e, kwargs)
                attempt += 1
                if isinstance(exc, ThroughputException):
                    if attempt > self.request_retries:
                        exc.re_raise()
                    self.exponential_sleep(attempt)
                else:
                    exc.re_raise()
        for hook in self._hooks['postcall']:
            hook(self, command, kwargs, data)
        if 'ConsumedCapacity' in data:
            is_read = command in READ_COMMANDS
            consumed = data['ConsumedCapacity']
            if isinstance(consumed, list):
                data['consumed_capacity'] = [
                    ConsumedCapacity.from_response(cap, is_read)
                    for cap in consumed
                ]
            else:
                capacity = ConsumedCapacity.from_response(consumed, is_read)
                data['consumed_capacity'] = capacity
        if 'consumed_capacity' in data:
            if isinstance(data['consumed_capacity'], list):
                all_caps = data['consumed_capacity']
            else:
                all_caps = [data['consumed_capacity']]
            for hook in self._hooks['capacity']:
                for cap in all_caps:
                    hook(self, command, kwargs, data, cap)
        return data