async def ingest(
        self,
        data: str | bytes,
        num_col_times_num_rows: int = 100,
        *args,
        **kwargs,
    ) -> AsyncGenerator[str, None]:
        """Ingest CSV data and yield text from each row."""
        if isinstance(data, bytes):
            data = data.decode("utf-8")
        # let the first row be the header
        delimiter = self.get_delimiter(file=self.StringIO(data))

        csv_reader = self.csv.reader(self.StringIO(data), delimiter=delimiter)

        header = next(csv_reader)
        num_cols = len(header.split(delimiter))
        num_rows = num_col_times_num_rows // num_cols

        chunk_rows = []
        for row_num, row in enumerate(csv_reader):
            chunk_rows.append(row)
            if row_num % num_rows == 0:
                yield (
                    ", ".join(header)
                    + "\n"
                    + "\n".join([", ".join(row) for row in chunk_rows])
                )
                chunk_rows = []

        if chunk_rows:
            yield (
                ", ".join(header)
                + "\n"
                + "\n".join([", ".join(row) for row in chunk_rows])
            )
Ingest CSV data and yield text from each row.
py/core/parsers/structured/csv_parser.py