File size: 3,167 Bytes
94516ce
646e4f3
9480219
94516ce
 
 
 
9480219
94516ce
 
 
 
 
 
 
 
 
 
8d505f4
 
 
 
c045a8c
9480219
 
8d505f4
 
 
 
 
 
94516ce
 
8d505f4
94516ce
8d505f4
 
 
94516ce
8d505f4
 
94516ce
8d505f4
 
 
4d83474
9480219
4d83474
 
 
 
8d505f4
9480219
8d505f4
 
 
 
94516ce
 
 
 
646e4f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94516ce
 
 
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
# app.py

import os
import gradio as gr
from text_extractor import extract_text_from_file
from embedder import get_embeddings
from vector_store import create_faiss_index, search_similar_cvs
from groq_api import summarize_match

# Global storage
cv_texts = []
cv_names = []
cv_vectors = []
faiss_index = None

def upload_cvs(files):
    global cv_texts, cv_names, cv_vectors, faiss_index

    try:
        cv_texts = [extract_text_from_file(f.name) for f in files]
        cv_names = [f.name for f in files]
        cv_vectors = get_embeddings(cv_texts)

        import numpy as np
        if cv_vectors is None or np.array(cv_vectors).size == 0:
            return "❌ No valid CVs extracted or embedded."

        faiss_index = create_faiss_index(cv_vectors)
        return f"βœ… Uploaded and indexed {len(files)} CVs."
    except Exception as e:
        return f"❌ Error during upload: {e}"

def match_jd(jd_text):
    global faiss_index

    try:
        if not faiss_index:
            return "❌ Please upload CVs first."

        if not jd_text.strip():
            return "❌ Job description is empty."

        jd_vector = get_embeddings([jd_text])[0]
        top_k_indices = search_similar_cvs(jd_vector, faiss_index, k=3)

        import os
        matched_names = [os.path.basename(cv_names[i]) for i in top_k_indices]
        matched_texts = [
            cv_texts[i][:500] if cv_texts[i].strip() else "[No CV content]"
            for i in top_k_indices
        ]

        summary = summarize_match(jd_text, matched_names, matched_texts)
        return f"βœ… Top Matches:\n{matched_names}\n\nπŸ“ Summary:\n{summary}"

    except Exception as e:
        return f"❌ Error during matching: {e}"

def clear_data():
    global cv_texts, cv_names, cv_vectors, faiss_index
    cv_texts, cv_names, cv_vectors, faiss_index = [], [], [], None
    return "🧹 All data cleared. You can now start fresh."

# 🌟 Redesigned Gradio Interface with Blocks
with gr.Blocks() as app:
    gr.Markdown("## πŸ“„ CV Filter App")
    gr.Markdown("Upload candidate CVs, enter a job description, and let AI find the top matches using Groq + FAISS.")

    with gr.Row():
        cv_upload = gr.File(label="πŸ“€ Upload CVs (PDF/DOCX)", file_types=[".pdf", ".docx"], file_count="multiple")
        upload_button = gr.Button("πŸ“ Upload & Index CVs")
        upload_status = gr.Textbox(label="Upload Status", interactive=False)

    with gr.Row():
        jd_input = gr.Textbox(label="πŸ“‹ Paste Job Description", lines=8, placeholder="Enter the job description here...")
        match_button = gr.Button("πŸ” Match CVs")
    
    match_result = gr.Textbox(label="πŸ“Š Matching Result & Summary", lines=12, interactive=False)

    with gr.Row():
        clear_button = gr.Button("🧹 Clear All")
        clear_output = gr.Textbox(label="Status", interactive=False)

    # Function bindings
    upload_button.click(fn=upload_cvs, inputs=[cv_upload], outputs=[upload_status])
    match_button.click(fn=match_jd, inputs=[jd_input], outputs=[match_result])
    clear_button.click(fn=clear_data, inputs=[], outputs=[clear_output])

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