Spaces:
Sleeping
Sleeping
# 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() | |