Spaces:
Sleeping
Sleeping
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 | |
} | |
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) | |
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.") | |
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' | |
) |