code: def search_reads(
              self, read_group_ids, reference_id=None, start=None, end=None):
          
          request = protocol.SearchReadsRequest()
          request.read_group_ids.extend(read_group_ids)
          request.reference_id = pb.string(reference_id)
          request.start = pb.int(start)
          request.end = pb.int(end)
          request.page_size = pb.int(self._page_size)
          return self._run_search_request(
              request, "reads", protocol.SearchReadsResponse)
docs: Returns an iterator over the Reads fulfilling the specified
          conditions from the specified read_group_ids.
  
          :param str read_group_ids: The IDs of the
              :class:`ga4gh.protocol.ReadGroup` of interest.
          :param str reference_id: The name of the
              :class:`ga4gh.protocol.Reference` we wish to return reads
              mapped to.
          :param int start: The start position (0-based) of this query. If a
              reference is specified, this defaults to 0. Genomic positions are
              non-negative integers less than reference length. Requests spanning
              the join of circular genomes are represented as two requests one on
              each side of the join (position 0).
          :param int end: The end position (0-based, exclusive) of this query.
              If a reference is specified, this defaults to the reference's
              length.
          :return: An iterator over the
              :class:`ga4gh.protocol.ReadAlignment` objects defined by
              the query parameters.
          :rtype: iter