File size: 3,111 Bytes
bb27315
 
9929265
0d3c88a
9929265
 
d5c1c41
bb27315
 
 
9929265
efadb61
bb27315
 
 
efadb61
 
 
f8a081e
31aa939
fc1e181
d7a756f
1fa36d8
f8a081e
9929265
 
 
 
 
 
 
1fa36d8
 
 
 
 
9929265
 
31aa939
9929265
 
d420b78
 
9929265
 
31aa939
9929265
 
efadb61
272e246
bb27315
9929265
bb27315
 
d7a756f
 
 
 
bb27315
 
 
 
a4c1be4
d7a756f
 
a4c1be4
 
efadb61
bb27315
 
 
 
9929265
bb27315
 
 
 
1fa36d8
bee3a95
d5c1c41
bb27315
 
 
 
 
 
 
9929265
bb27315
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import gradio as gr
import os
import shutil
from recommender import rank_resumes, summarize_resume_flan, extract_applicant_name
from docx import Document
import pdfplumber

UPLOAD_FOLDER = "uploads"
os.makedirs(UPLOAD_FOLDER, exist_ok=True)


def process_resumes(job_description, uploaded_files):
    if not job_description.strip():
        return "Please provide a job description.", None

    resume_texts = []

    for uploaded_file in uploaded_files:
        filename = os.path.basename(uploaded_file.name)
        ext = filename.lower().split(".")[-1]

        # Copying the file from Gradio temp folder to uploads folder
        file_path = os.path.join(UPLOAD_FOLDER, filename)
        shutil.copy(uploaded_file.name, file_path)

        if ext == "txt":
            with open(file_path, "r", encoding="utf-8") as f:
                text = f.read()

        elif ext == "pdf":
            try:
                with pdfplumber.open(file_path) as pdf:
                    pages = [page.extract_text() for page in pdf.pages if page.extract_text() is not None]
                    if not pages:
                        return f"No extractable text found in PDF: {filename}. Is it scanned or image-only?", None
                    text = "\n".join(pages)
            except Exception as e:
                return f"Failed to process PDF {filename}: {str(e)}", None

        elif ext == "docx":
            try:
                doc = Document(file_path)
                text = "\n".join([p.text for p in doc.paragraphs])
            except Exception as e:
                return f"Failed to process DOCX {filename}: {str(e)}", None

        else:
            return f"Unsupported file format: {filename}", None

        resume_texts.append((filename, text))

    # Rank resumes and generate summaries
    results = rank_resumes(job_description, resume_texts)

    # Attach filename to each candidate for display
    for i, candidate in enumerate(results):
        candidate["filename"] = resume_texts[i][0]

    for candidate in results:
        candidate["summary"] = summarize_resume_flan(candidate["text"], job_description)

    table_data = [
        [
            candidate.get("applicant_name", extract_applicant_name(candidate["text"], candidate.get("filename", "Unknown"))),
            candidate.get("filename", "Unknown"),
            f"{candidate['score']:.4f}",
            candidate["summary"]
        ] for candidate in results
    ]

    return "", table_data


with gr.Blocks() as demo:
    gr.Markdown("## Candidate Recommendation Engine")
    with gr.Row():
        job_desc = gr.Textbox(label="Job Description", lines=10, placeholder="Paste job description here...")

    resumes = gr.Files(label="Upload Resumes (.txt, .pdf, .docx)", file_types=[".txt", ".pdf", ".docx"])

    btn = gr.Button("Rank Candidates")

    msg = gr.Markdown()
    output_table = gr.Dataframe(headers=["Candidate", "File Name", "Similarity Score", "Why a Good Fit"], wrap=True)

    btn.click(process_resumes, inputs=[job_desc, resumes], outputs=[msg, output_table])


if __name__ == "__main__":
    demo.launch()