Spaces:
Sleeping
Sleeping
| """CSV/TSV reader — converts delimited files to markdown tables.""" | |
| from __future__ import annotations | |
| import csv | |
| from pathlib import Path | |
| from uofa_cli.document_reader import DocumentChunk | |
| def read_csv(path: Path, row_budget: int = 50) -> list[DocumentChunk]: | |
| """Read a CSV/TSV and return a single chunk as a markdown table.""" | |
| text_content = _read_with_encoding(path) | |
| # Auto-detect delimiter | |
| try: | |
| dialect = csv.Sniffer().sniff(text_content[:4096], delimiters=",\t;|") | |
| delimiter = dialect.delimiter | |
| except csv.Error: | |
| delimiter = "," if path.suffix.lower() == ".csv" else "\t" | |
| reader = csv.reader(text_content.splitlines(), delimiter=delimiter) | |
| rows = list(reader) | |
| if not rows: | |
| return [DocumentChunk( | |
| text="(empty CSV file)", | |
| source_file=path.name, | |
| source_path=str(path), | |
| format="csv", | |
| )] | |
| header = rows[0] | |
| data_rows = rows[1:] | |
| total_rows = len(data_rows) | |
| truncated = total_rows > row_budget | |
| display_rows = data_rows[:row_budget] | |
| n_cols = len(header) | |
| md_lines = [ | |
| f"| {' | '.join(header)} |", | |
| f"| {' | '.join(['---'] * n_cols)} |", | |
| ] | |
| for row in display_rows: | |
| cells = row[:n_cols] | |
| while len(cells) < n_cols: | |
| cells.append("") | |
| md_lines.append(f"| {' | '.join(cells)} |") | |
| if truncated: | |
| md_lines.append(f"(showing {row_budget} of {total_rows} rows — full data in source file)") | |
| text = f"({total_rows} rows x {n_cols} cols)\n" | |
| text += "\n".join(md_lines) | |
| return [DocumentChunk( | |
| text=text, | |
| source_file=path.name, | |
| source_path=str(path), | |
| format="csv", | |
| )] | |
| def _read_with_encoding(path: Path) -> str: | |
| """Read file with UTF-8, falling back to chardet detection.""" | |
| try: | |
| return path.read_text(encoding="utf-8") | |
| except UnicodeDecodeError: | |
| pass | |
| try: | |
| import chardet | |
| raw = path.read_bytes() | |
| detected = chardet.detect(raw) | |
| encoding = detected.get("encoding", "utf-8") or "utf-8" | |
| return raw.decode(encoding, errors="replace") | |
| except ImportError: | |
| return path.read_text(encoding="utf-8", errors="replace") | |