import os import httpx from dotenv import load_dotenv from fastapi import FastAPI, UploadFile, File, HTTPException, Form from fastapi.middleware.cors import CORSMiddleware import uvicorn from rfq_parser import parse_rfq_pdf, LLAMA_API_BASE_DEFAULT, LLAMA_MODEL_DEFAULT load_dotenv() app = FastAPI(title="Dynamic RFQ Parser") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.post("/parse-rfq") async def parse_rfq( file: UploadFile = File(...), provider: str = Form("gemini"), ): if not file.filename.endswith(".pdf"): raise HTTPException(status_code=400, detail="Only PDF files are supported") if provider not in ("gemini", "ollama", "llama", "none"): raise HTTPException(status_code=400, detail="provider must be 'gemini', 'ollama', 'llama', or 'none'") if provider == "gemini" and not os.getenv("GOOGLE_API_KEY"): raise HTTPException(status_code=500, detail="GOOGLE_API_KEY not configured") if provider == "ollama" and not os.getenv("OLLAMA_MODEL"): raise HTTPException(status_code=500, detail="OLLAMA_MODEL not configured") if provider == "llama": base_url = os.getenv("LLAMA_API_BASE", LLAMA_API_BASE_DEFAULT) try: resp = httpx.get(f"{base_url}/models", timeout=5) resp.raise_for_status() except Exception: raise HTTPException(status_code=503, detail=f"llama.cpp server not reachable at {base_url}") contents = await file.read() try: result = parse_rfq_pdf(contents, provider=provider) return result except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @app.get("/providers") def list_providers(): llama_base = os.getenv("LLAMA_API_BASE", LLAMA_API_BASE_DEFAULT) llama_model = os.getenv("LLAMA_MODEL", LLAMA_MODEL_DEFAULT) llama_available = False try: resp = httpx.get(f"{llama_base}/models", timeout=3) llama_available = resp.status_code == 200 except Exception: pass return { "providers": [ { "id": "gemini", "available": bool(os.getenv("GOOGLE_API_KEY")), "config": {"model": "gemini-2.5-pro"}, }, { "id": "ollama", "available": bool(os.getenv("OLLAMA_MODEL")), "config": { "model": os.getenv("OLLAMA_MODEL", ""), "host": os.getenv("OLLAMA_HOST", "http://localhost:11434"), }, }, { "id": "llama", "available": llama_available, "config": { "base_url": llama_base, "model": llama_model, }, }, { "id": "none", "available": True, "config": {}, }, ] } @app.get("/health") def health(): return {"status": "ok"} if __name__ == "__main__": port = int(os.getenv("PORT", "7860")) uvicorn.run("main:app", host="0.0.0.0", port=port)