def ExecuteRequest(client: 'botocore.client.EC2',
                   func: str,
                   kwargs: Dict[str, Any]) -> List[Dict[str, Any]]:
  """Execute a request to the boto3 API.

  Args:
    client (boto3.session.Session): A boto3 client object.
    func (str): A boto3 function to query from the client.
    kwargs (Dict): A dictionary of parameters for the function func. Expected
        keys are strings, values can be of multiple types. E.g.:
        {'InstanceIds': ['instance_id'], 'MaxResults': 12}.

  Returns:
    List[Dict]: A list of dictionaries (responses from the
        request), e.g. [{'Groups': [{...}], 'Instances': [{...}]}, {...}]

  Raises:
    RuntimeError: If the request to the boto3 API could not complete.
  """
  responses = []
  next_token = None
  while True:
    if next_token:
      kwargs['NextToken'] = next_token
    request = getattr(client, func)
    try:
      response = request(**kwargs)
    except client.exceptions.ClientError as exception:
      raise RuntimeError('Could not process request: {0:s}'.format(
          str(exception))) from exception
    responses.append(response)
    next_token = response.get('NextToken')
    if not next_token:
      return responses
Execute a request to the boto3 API.

Args:
client (boto3.session.Session): A boto3 client object.
func (str): A boto3 function to query from the client.
kwargs (Dict): A dictionary of parameters for the function func. Expected
keys are strings, values can be of multiple types. E.g.:
{'InstanceIds': ['instance_id'], 'MaxResults': 12}.

Returns:
List[Dict]: A list of dictionaries (responses from the
request), e.g. [{'Groups': [{...}], 'Instances': [{...}]}, {...}]

Raises:
RuntimeError: If the request to the boto3 API could not complete.
libcloudforensics/providers/aws/internal/common.py