from fastapi import FastAPI, UploadFile, File, HTTPException from fastapi.responses import PlainTextResponse from fastapi.responses import JSONResponse from fastapi.middleware.cors import CORSMiddleware from fastapi import Request import joblib import PyPDF2 import re import logging import tempfile import os app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) logging.basicConfig(level=logging.INFO) try: model = joblib.load("react_classifier.joblib") except Exception as e: logging.error(f"Erro ao carregar o modelo: {e}") raise def clean_text(text): text = text.lower() text = re.sub(r'[^\w\s]', ' ', text) text = re.sub(r'\s+', ' ', text) return text.strip() def extract_text_from_pdf(file_path): text = "" try: with open(file_path, 'rb') as f: reader = PyPDF2.PdfReader(f) for page in reader.pages: page_text = page.extract_text() if page_text: text += page_text + "\n" except Exception as e: raise Exception(f"Erro ao extrair texto do PDF: {e}") return text def avaliar_candidato( anosEstudoTecnologia: int, tempoDesenvolvedor: int, tempoExperiencia: int, nivelIngles: int, graduacao: int ) -> dict: score_estudo = anosEstudoTecnologia / 6 score_desenvolv = tempoDesenvolvedor / 6 score_experiencia = tempoExperiencia / 6 score_ingles = nivelIngles / 4 score_graduacao = graduacao / 7 peso_estudo = 0.15 peso_desenvolv = 0.2 peso_experiencia = 0.3 peso_ingles = 0.25 peso_graduacao = 0.1 score_final = ( score_estudo * peso_estudo + score_desenvolv * peso_desenvolv + score_experiencia * peso_experiencia + score_ingles * peso_ingles + score_graduacao * peso_graduacao ) score_percentual = round(score_final * 100, 2) aprovado = score_percentual >= 70.0 return { "score": score_percentual, "aprovado": aprovado } @app.post("/classificar") async def classify_resume(file: UploadFile = File(...)): try: suffix = os.path.splitext(file.filename)[-1] with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as temp: temp.write(await file.read()) temp_path = temp.name raw_text = extract_text_from_pdf(temp_path) cleaned = clean_text(raw_text) proba = model.predict_proba([cleaned])[0] prediction = model.predict([cleaned])[0] result = { "classificacao": "React Developer" if prediction == 1 else "Outra Área", "probabilidade": f"{proba[1]*100:.2f}%", "trecho_texto": cleaned[:500] + "..." if len(cleaned) > 500 else cleaned } return JSONResponse(content=result) except Exception as e: logging.error(f"Erro no processamento: {e}") raise HTTPException(status_code=500, detail=str(e)) finally: if 'temp_path' in locals() and os.path.exists(temp_path): os.remove(temp_path) @app.post("/avaliar") async def avaliar_formulario(request: Request): try: data = await request.json() resultado = avaliar_candidato( anosEstudoTecnologia=int(data.get("anosEstudoTecnologia", 0)), tempoDesenvolvedor=int(data.get("tempoDesenvolvedor", 0)), tempoExperiencia=int(data.get("tempoExperiencia", 0)), nivelIngles=int(data.get("nivelIngles", 0)), graduacao=int(data.get("graduacao", 0)) ) return JSONResponse( status_code=200, content={ "avaliacao": "Aprovado" if resultado["aprovado"] else "Reprovado", "score": resultado["score"] } ) except Exception as e: logging.error(f"Erro na avaliação do formulário: {e}") raise HTTPException(status_code=500, detail="Erro ao processar os dados.") @app.get("/", response_class=PlainTextResponse) async def root(): return ( "Esta API possui duas rotas POST:\n" " /classificar → espera um arquivo PDF de currículo\n" " /avaliar → espera um JSON como este:\n" '{\n' ' "anosEstudoTecnologia": 6,\n' ' "tempoDesenvolvedor": 6,\n' ' "tempoExperiencia": 6,\n' ' "nivelIngles": 3,\n' ' "graduacao": 7\n' '}\n' )