docs: def get(self, stream, start_time, end_time, start_id=None, limit=None,
            order=ResultOrder.ASCENDING, namespace=None, timeout=None):
      """
      Queries a stream with name `stream` for all events between `start_time` and
      `end_time` (both inclusive).  An optional `start_id` allows the client to
      restart from a failure, specifying the last ID they read; all events that
      happened after that ID will be returned. An optional `limit` limits the
      maximum number of events returned.  An optional `order` requests results in
      `ASCENDING` or `DESCENDING` order.
      """
      if isinstance(start_time, types.StringTypes):
        start_time = parse(start_time)
      if isinstance(end_time, types.StringTypes):
        end_time = parse(end_time)
      if isinstance(start_time, datetime):
        start_time = datetime_to_kronos_time(start_time)
      if isinstance(end_time, datetime):
        end_time = datetime_to_kronos_time(end_time)
  
      request_dict = {
        'stream': stream,
        'end_time': end_time,
        'order': order,
      }
      if start_id is not None:
        request_dict['start_id'] = start_id
      else:
        request_dict['start_time'] = start_time
  
      if limit is not None:
        request_dict['limit'] = limit
  
      namespace = namespace or self.namespace
      if namespace is not None:
        request_dict['namespace'] = namespace
  
      errors = []
      last_id = None
      while True:
        try:
          response = self._make_request(self._get_url,
                                        data=request_dict,
                                        stream=True,
                                        timeout=timeout)
          for line in response.iter_lines(chunk_size=self._chunk_size):
            if line:
              # Python's json adds a lot of overhead when decoding a large
              # number of events; ujson fares better. However ujson won't work
              # on PyPy since it's a C extension.
              event = ujson.loads(line, precise_float=True)
              last_id = event[ID_FIELD]
              yield event
          break
        except Exception, e:
          if isinstance(e, requests.exceptions.Timeout):
            raise KronosClientError('Request timed out.')
          errors.append(e)
          if len(errors) == 10:
            raise KronosClientError(errors)
          if last_id is not None:
            request_dict.pop('start_time', None)
            request_dict['start_id'] = last_id
          time.sleep(len(errors) * 0.1)