'Returns a list of input readers for the input spec.
Args:
mapper_spec: The MapperSpec for this InputReader. Must contain
\'blob_keys\' parameter with one or more blob keys.
_reader: a callable that returns a file-like object for reading blobs.
Used for dependency injection.
Returns:
A list of InputReaders spanning the subfiles within the blobs.
There will be at least one reader per blob, but it will otherwise
attempt to keep the expanded size even.
Raises:
BadReaderParamsError: required parameters are missing or invalid.'

@classmethod
def split_input(cls, mapper_spec, _reader=blobstore.BlobReader):

    if (mapper_spec.input_reader_class() != cls):
        raise BadReaderParamsError('Mapper    input    reader    class    mismatch')
    params = mapper_spec.params
    if (cls.BLOB_KEYS_PARAM not in params):
        raise BadReaderParamsError("Must    specify    'blob_key'    for    mapper    input")
    blob_keys = params[cls.BLOB_KEYS_PARAM]
    if isinstance(blob_keys, basestring):
        blob_keys = blob_keys.split(',')
    if (len(blob_keys) > cls._MAX_BLOB_KEYS_COUNT):
        raise BadReaderParamsError("Too    many    'blob_keys'    for    mapper    input")
    if (not blob_keys):
        raise BadReaderParamsError("No    'blob_keys'    specified    for    mapper    input")
    blob_files = {}
    total_size = 0
    for blob_key in blob_keys:
        zip_input = zipfile.ZipFile(_reader(blob_key))
        blob_files[blob_key] = zip_input.infolist()
        total_size += sum((x.file_size for x in blob_files[blob_key]))
    shard_count = min(cls._MAX_SHARD_COUNT, mapper_spec.shard_count)
    size_per_shard = (total_size // shard_count)
    readers = []
    for blob_key in blob_keys:
        files = blob_files[blob_key]
        current_shard_size = 0
        start_file_index = 0
        next_file_index = 0
        for fileinfo in files:
            next_file_index += 1
            current_shard_size += fileinfo.file_size
            if (current_shard_size >= size_per_shard):
                readers.append(cls(blob_key, start_file_index, next_file_index, 0, _reader))
                current_shard_size = 0
                start_file_index = next_file_index
        if (current_shard_size != 0):
            readers.append(cls(blob_key, start_file_index, next_file_index, 0, _reader))
    return readers
