import os from dotenv import load_dotenv load_dotenv() import pandas as pd import io import uuid from fastapi import FastAPI, UploadFile, File, HTTPException from fastapi.middleware.cors import CORSMiddleware from app.models.schemas import EvaluationRequest, EvaluationResponse, Candidate from app.services.evaluation_service import evaluate_candidate import asyncio app = FastAPI(title="AI Recruitment Engine") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) # In-memory storage for demonstration (Production should use DB) evaluations_cache = {} @app.post("/upload-csv") async def upload_csv(file: UploadFile = File(...)): if not file.filename.endswith('.csv'): raise HTTPException(status_code=400, detail="Invalid file format. Please upload a CSV.") try: content = await file.read() df = pd.read_csv(io.BytesIO(content)) df = df.fillna("") candidates = [] for _, row in df.iterrows(): candidates.append(Candidate( id=str(uuid.uuid4()), name=str(row.get("name", "Unknown")), email=str(row.get("email", "")), skills=str(row.get("skills", "")), experience=str(row.get("experience", "")), projects=str(row.get("projects", "")), education=str(row.get("education", "")), resume_text=str(row.get("resume_text", "")) )) return {"candidates": candidates} except Exception as e: raise HTTPException(status_code=500, detail=f"Error parsing CSV: {str(e)}") @app.post("/evaluate", response_model=EvaluationResponse) async def evaluate(request: EvaluationRequest): if not request.jd: raise HTTPException(status_code=400, detail="Job Description is required.") if not request.candidates: raise HTTPException(status_code=400, detail="No candidates provided.") from app.services.evaluation_service import perform_hybrid_evaluation response = await perform_hybrid_evaluation(request.jd, request.candidates) # Store in cache for detail retrieval for rank in response.shortlist: evaluations_cache[rank.candidate_id] = rank # Also store the deep review details evaluations_cache.update(response.details) return response @app.get("/results") async def get_results(): return list(evaluations_cache.values()) @app.get("/candidate/{id}") async def get_candidate_report(id: str): if id not in evaluations_cache: raise HTTPException(status_code=404, detail="Candidate report not found.") return evaluations_cache[id] if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)