Spaces:
Sleeping
Sleeping
File size: 4,482 Bytes
96a2583 683fe66 96a2583 | 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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | # ============================================================
# app.py β TalentMatch AI on Hugging Face Spaces
# This file runs the web interface using Gradio.
# Hugging Face automatically runs this file when your Space loads.
# ============================================================
import gradio as gr
import pandas as pd
from preprocess import full_preprocess
from skill_extractor import extract_skills, skill_match_percentage
from matcher import rank_candidates
# ββ Load and preprocess data when the app FIRST starts ββββββ
# This runs ONCE when someone opens the Space β then it's ready.
print("Loading dataset...")
df = pd.read_csv("data/ats_resume_dataset_elite_v3.csv")
print("Preprocessing all resumes (this takes ~30 seconds)...")
df['cleaned_resume'] = df['resume_text'].apply(full_preprocess)
print("TalentMatch AI is ready!")
# ββ The main function that Gradio calls ββββββββββββββββββββββ
def screen_candidates(job_description, num_results):
"""
Takes a job description and returns the top matching candidates.
This function is called every time someone clicks 'Submit'.
"""
# Handle empty input
if not job_description.strip():
return pd.DataFrame({"Message": ["Please paste a job description in the box above."]})
# Extract skills from the job description
job_skills = extract_skills(job_description)
# Rank all candidates using TF-IDF + Cosine Similarity
top_candidates = rank_candidates(df, job_description, top_n=int(num_results))
# Build a clean results table
results = []
for rank, (_, row) in enumerate(top_candidates.iterrows(), start=1):
resume_skills = extract_skills(str(row['resume_text']))
match_pct = skill_match_percentage(resume_skills, job_skills)
results.append({
'Rank' : rank,
'Resume ID' : row['resume_id'],
'Job Role' : row['job_role'],
'Experience' : f"{row['experience_years']} yrs",
'Education' : row['education_level'],
'ATS Score' : round(row['computed_similarity'], 3),
'Skill Match' : f"{int(match_pct * 100)}%",
'Shortlisted' : 'YES β
' if row['shortlisted'] == 1 else 'NO',
})
return pd.DataFrame(results)
# ββ Build the Gradio web interface βββββββββββββββββββββββββββ
demo = gr.Interface(
fn=screen_candidates,
inputs=[
gr.Textbox(
label="Paste Job Description Here",
placeholder=(
"Example:\n"
"We are looking for a Data Scientist.\n"
"Required skills: Python, Machine Learning, SQL, pandas, scikit-learn.\n"
"Minimum 2 years experience required."
),
lines=7
),
gr.Slider(
minimum=5,
maximum=20,
value=10,
step=1,
label="Number of Top Candidates to Show"
),
],
outputs=gr.Dataframe(
label="Top Matching Candidates β Ranked by AI",
wrap=True
),
title="TalentMatch AI β ATS Resume Screening System",
description=(
"Built using NLP, TF-IDF Vectorization, and Cosine Similarity. "
"Paste any job description β AI ranks 6,000 resumes in seconds. "
"Built by an Undergraduate CS Student."
),
examples=[
[
"We need a Data Scientist with Python, Machine Learning, TensorFlow, SQL, and pandas. "
"2+ years experience required. Knowledge of NLP and deep learning is a plus.",
10
],
[
"Looking for a Frontend Developer skilled in React, JavaScript, HTML, CSS, and Node.js. "
"Must know REST APIs and Git. Fresh graduates welcome.",
8
],
[
"Hiring ML Engineer with PyTorch, scikit-learn, Docker, AWS, and Python. "
"Must have experience with model deployment and feature engineering.",
10
],
],
theme=gr.themes.Soft(),
)
# ββ Launch the app ββββββββββββββββββββββββββββββββββββββββββββ
# On Hugging Face, demo.launch() with no arguments is correct.
# Locally, use demo.launch(share=True) to get a public link.
demo.launch()
|