from sqlalchemy.orm import Session from datetime import datetime from typing import Optional from fastapi import HTTPException from app.modules.edos.models import EDOS from app.modules.edos.schema import EdosResponse, EdosUpload, messageResponse from app.helpers.csv_mapper import CSVMapper from app.helpers.db_adapter import DBAdapter from app.helpers.extractCsv import CSVExtractor class XMACSVService: """ Orquester""" @staticmethod def process_csv_from_url( csv_url: str, dry_run: bool = False, max_rows: int = None ) -> dict: """ flow download and parsing, filter and adapt""" try: # X - EXTRACT print(f"📥 Descargando CSV: {csv_url}") # ✅ Ahora download_csv retorna (content, encoding) content, encoding = CSVExtractor.download_csv(csv_url) print(f" ✅ Descargado {len(content)} bytes, encoding: {encoding}") # Parsear CSV raw_rows = CSVExtractor.read_csv(content) print(f" ✅ Parseadas {len(raw_rows)} filas") if not raw_rows: return { 'total_extracted': 0, 'total_mapped': 0, 'inserted': 0, 'errors': ['No se encontraron datos en el CSV'] } # Mostrar columnas encontradas print(f" 📋 Columnas: {list(raw_rows[0].keys())}") # M - MAP (si tienes mapper) # Por ahora, usar datos crudos mapped_rows = raw_rows if max_rows: mapped_rows = mapped_rows[:max_rows] print(f" 🔒 Limitado a {max_rows} filas") # A - ADAPT if not dry_run: print(f" 💾 Insertando {len(mapped_rows)} filas en BD") # Aquí iría la inserción en BD return { 'total_extracted': len(raw_rows), 'total_mapped': len(mapped_rows), 'inserted': len(mapped_rows) if not dry_run else 0, 'dry_run': dry_run, 'columns': list(raw_rows[0].keys()) if raw_rows else [], 'sample': raw_rows[:2] if raw_rows else [] } except Exception as e: print(f"❌ Error: {str(e)}") import traceback traceback.print_exc() raise