A Flask web app that ranks uploaded resumes against a job description using TF-IDF cosine similarity, and generates an AI summary of each candidate using Google's Gemini model via LangChain.
Screening a stack of resumes against a single job description is repetitive, manual work. This app automates the first pass: an HR user logs in, pastes a job description, uploads a batch of PDF resumes, and gets back a ranked shortlist — each candidate scored by relevance and summarized in plain language.
1. Text extraction — each uploaded PDF resume is parsed with PyPDF2 to pull raw text.
2. Relevance ranking — the job description and every resume are vectorized with TfidfVectorizer, then ranked by cosine similarity against the job description, surfacing the closest match first.
3. AI summarization — each resume's text is sent to Gemini 1.5 Flash through LangChain's ChatGoogleGenerativeAI, producing a short summary alongside its score.
4. Persistence — job descriptions, resume text, scores, and summaries are logged to a local SQLite database for later review.
def rank_resumes(job_description, resumes):
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
documents = [job_description] + resumes
vectorizer = TfidfVectorizer().fit_transform(documents)
vectors = vectorizer.toarray()
job_vector = vectors[0]
resume_vectors = vectors[1:]
return cosine_similarity([job_vector], resume_vectors).flatten()
# Gemini-powered candidate summary, via LangChain
def summarize_text(text):
llm = ChatGoogleGenerativeAI(model="gemini-1.5-flash", google_api_key=google_api_key)
prompt = f"Summarize the following pdf resumes: {text[:1500]}"
return llm.invoke(prompt).content.strip()
.env file holding that API key is intentionally excluded from this repository.