GraphResearcher / app /ingestion /csv_excel_parser.py
yugbirla's picture
Sync GraphRAG fusion quality cleanup and evaluation files
b7d0804
Raw
History Blame Contribute Delete
3.73 kB
from pathlib import Path
from typing import List, Dict, Any
import pandas as pd
from app.core.config import settings
from app.ingestion.base_parser import BaseParser
from app.schemas.rich_content_block import RichContentBlock
class CsvExcelParser(BaseParser):
def parse(
self,
file_path: str,
document_id: str,
source_file_name: str
) -> List[RichContentBlock]:
extension = Path(source_file_name).suffix.lower()
if extension == ".csv":
sheets = {"csv": read_csv_safely(file_path)}
elif extension in [".xlsx", ".xls"]:
sheets = pd.read_excel(file_path, sheet_name=None)
else:
raise ValueError(f"Unsupported table file extension: {extension}")
blocks = []
block_counter = 1
for sheet_name, dataframe in sheets.items():
dataframe = clean_dataframe(dataframe)
if dataframe.empty:
continue
for start_row in range(0, len(dataframe), settings.MAX_ROWS_PER_TABLE_BLOCK):
end_row = min(start_row + settings.MAX_ROWS_PER_TABLE_BLOCK, len(dataframe))
batch_df = dataframe.iloc[start_row:end_row]
table_json = batch_df.to_dict(orient="records")
markdown_table = dataframe_to_markdown(batch_df)
blocks.append(
RichContentBlock(
block_id=f"{document_id}_table_block_{block_counter}",
document_id=document_id,
content_type="table",
content=markdown_table,
page_number=None,
section_title=f"Sheet: {sheet_name}",
source_file_name=source_file_name,
metadata={
"parser": "CsvExcelParser",
"original_format": extension,
"sheet_name": sheet_name,
"table_json": table_json,
"columns": list(batch_df.columns),
"row_start": start_row + 1,
"row_end": end_row,
"total_rows_in_sheet": len(dataframe),
"max_rows_per_table_block": settings.MAX_ROWS_PER_TABLE_BLOCK
}
)
)
block_counter += 1
return blocks
def read_csv_safely(file_path: str) -> pd.DataFrame:
try:
return pd.read_csv(file_path)
except UnicodeDecodeError:
return pd.read_csv(file_path, encoding="latin1")
def clean_dataframe(dataframe: pd.DataFrame) -> pd.DataFrame:
dataframe = dataframe.copy()
dataframe = dataframe.dropna(how="all")
dataframe = dataframe.dropna(axis=1, how="all")
dataframe.columns = [
str(column).strip() if str(column).strip() else f"column_{index + 1}"
for index, column in enumerate(dataframe.columns)
]
dataframe = dataframe.fillna("")
for column in dataframe.columns:
dataframe[column] = dataframe[column].astype(str)
return dataframe
def dataframe_to_markdown(dataframe: pd.DataFrame) -> str:
columns = [str(column) for column in dataframe.columns]
lines = []
lines.append("| " + " | ".join(columns) + " |")
lines.append("| " + " | ".join(["---"] * len(columns)) + " |")
for _, row in dataframe.iterrows():
values = [
str(row[column]).replace("|", "\\|").replace("\n", " ").strip()
for column in columns
]
lines.append("| " + " | ".join(values) + " |")
return "\n".join(lines)