Gemma / app.py
ShubhamD95's picture
Update app.py
b925d82 verified
import gradio as gr
from transformers import pipeline
import re
import os
from huggingface_hub import login
import spacy
from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS
# Authenticate with Hugging Face
login(token=os.environ.get("HUGGINGFACEHUB_API_TOKEN"))
# Load summarization model
summarizer = pipeline("text2text-generation", model="declare-lab/flan-alpaca-base")
# Load SpaCy English model
nlp = spacy.load("en_core_web_sm")
# πŸ” Use SpaCy to extract nouns and proper nouns (contextually relevant keywords)
def extract_relevant_keywords(text):
doc = nlp(text.lower())
return set(
token.text for token in doc
if token.pos_ in {"NOUN", "PROPN"} and not token.is_stop and len(token.text) > 2
)
# Compare keywords with semantic filtering
def compare_keywords(resume_text, job_desc):
resume_words = extract_relevant_keywords(resume_text)
job_words = extract_relevant_keywords(job_desc)
matched = resume_words & job_words
missing = job_words - resume_words
return matched, missing
# Highlight matched keywords in the resume
def highlight_keywords(resume_text, matched):
highlighted = resume_text
for word in sorted(matched, key=len, reverse=True):
highlighted = re.sub(rf"\b({re.escape(word)})\b", r"**\1**", highlighted, flags=re.IGNORECASE)
return highlighted
# LLM-based missing keyword extraction
def extract_missing_keywords_with_llm(job_desc, resume_text):
prompt = f"""
Given the following job description and resume, list the important skills, tools, and concepts from the job description that are missing or weakly represented in the resume.
Job Description:
{job_desc}
Resume:
{resume_text}
Only list the missing keywords as bullet points.
"""
result = summarizer(prompt, max_new_tokens=300, do_sample=True)[0]
return result.get('generated_text', result.get('summary_text', str(result))).strip()
# Resume improvement prompt
def build_dynamic_prompt(job_desc, resume_text, analyze_with_jd):
prompt = f"""
Analyze the resume below and organize it into meaningful categories (e.g., Skills, Education, Work Experience, etc.).
If a job description is provided, compare it against the resume and suggest improvements section by section.
Job Description:
{job_desc if analyze_with_jd else '[None provided]'}
Resume:
{resume_text}
Return structured Markdown with headers for each section and improvement suggestions.
"""
return prompt
# Generate analysis result
def analyze_resume(job_desc, resume_text, analyze_with_jd):
if not resume_text.strip():
return "⚠️ Please paste your resume text."
user_prompt = build_dynamic_prompt(job_desc, resume_text, analyze_with_jd)
try:
result = summarizer(user_prompt, max_new_tokens=512, do_sample=True)[0]
response_text = result.get('generated_text', result.get('summary_text', str(result))).strip()
if analyze_with_jd and job_desc:
matched, missing = compare_keywords(resume_text, job_desc)
highlighted_resume = highlight_keywords(resume_text, matched)
llm_missing_keywords = extract_missing_keywords_with_llm(job_desc, resume_text)
return f"""### πŸ” Resume with Highlighted Matches
{highlighted_resume}
---
** Matched Keywords (Semantic Comparison):**
{', '.join(sorted(matched)) or 'None'}
** Missing Keywords (Semantic Comparison):**
{', '.join(sorted(missing)) or 'None'}
** LLM-Inferred Missing Keywords:**
{llm_missing_keywords}
---
{response_text}"""
return response_text
except Exception as e:
return f"❌ Error: {str(e)}"
# Gradio Interface
def create_ui():
with gr.Blocks() as demo:
with gr.Row():
with gr.Column():
analyze_checkbox = gr.Checkbox(label="Analyze with Job Description", value=True)
job_desc = gr.Textbox(label="Job Description", lines=6, placeholder="Paste job description here...")
resume_text = gr.Textbox(label="Resume Text", lines=16, placeholder="Paste resume content here...")
analyze_button = gr.Button("Run Analysis")
with gr.Column():
output_analysis = gr.Markdown(label="Resume Analysis and Suggestions")
analyze_button.click(fn=analyze_resume, inputs=[job_desc, resume_text, analyze_checkbox], outputs=output_analysis)
return demo
if __name__ == '__main__':
create_ui().launch()