"""GMAL data ingestion endpoint.""" import logging import os from fastapi import APIRouter, HTTPException, UploadFile, File from sqlalchemy import create_engine from sqlalchemy.orm import Session from app.config import settings from app.schemas.gmal import IngestResult from app.services.excel_parser import parse_gmal_workbook router = APIRouter() logger = logging.getLogger(__name__) @router.post("/ingest", response_model=IngestResult) async def ingest_gmal_data(file: UploadFile | None = File(None)): """Ingest GMAL data from Excel file. If no file is uploaded, uses the default file from the data directory. Uses a synchronous DB session since openpyxl is synchronous. """ if file: # Save uploaded file temporarily filepath = f"/tmp/{file.filename}" content = await file.read() with open(filepath, "wb") as f: f.write(content) else: # Use default data file filepath = os.path.join(settings.data_dir, "U-Studio GMAL Asset Job Routes Apr25 ForFranky.xlsx") if not os.path.exists(filepath): raise HTTPException(status_code=404, detail="Default GMAL file not found in data directory") # Use sync engine for openpyxl parsing sync_engine = create_engine(settings.database_url_sync) try: with Session(sync_engine) as db: result = parse_gmal_workbook(filepath, db) return IngestResult(**result) except Exception as e: logger.error(f"Ingestion failed: {e}", exc_info=True) raise HTTPException(status_code=500, detail=f"Ingestion failed: {str(e)}") finally: sync_engine.dispose() if file and os.path.exists(filepath): os.remove(filepath)