# app/main.py import os import uuid import json import logging from fastapi import FastAPI, UploadFile, File, Form, HTTPException from fastapi.middleware.cors import CORSMiddleware from starlette.responses import JSONResponse from .pipeline import process_file logger = logging.getLogger("uvicorn.error") app = FastAPI(title="HF-Space Data Pipeline API") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) TMP_DIR = os.getenv("TMP_DIR", "/tmp") os.makedirs(TMP_DIR, exist_ok=True) @app.get("/health") def health(): return {"status": "ok"} @app.post("/process-file") async def process_file_endpoint(file: UploadFile = File(...), sheet: str = Form(None)): # save uploaded file to /tmp and process synchronously (deterministic) filename = file.filename or f"upload-{uuid.uuid4().hex}" safe_name = f"{uuid.uuid4().hex}-{filename}" path = os.path.join(TMP_DIR, safe_name) try: contents = await file.read() with open(path, "wb") as f: f.write(contents) except Exception as e: raise HTTPException(status_code=500, detail=f"failed to save upload: {e}") try: result = process_file(path, sheet=sheet) except Exception as e: logger.exception("processing failed") raise HTTPException(status_code=500, detail=f"processing failed: {e}") return JSONResponse(content=result) # convenience route to process an existing file path inside the container (dev/testing) @app.post("/process-path") def process_path_endpoint(path: str, sheet: str = None): if not os.path.exists(path): raise HTTPException(status_code=404, detail="file not found") try: result = process_file(path, sheet=sheet) except Exception as e: logger.exception("processing failed") raise HTTPException(status_code=500, detail=f"processing failed: {e}") return JSONResponse(content=result)