Spaces:
Running
Running
File size: 4,614 Bytes
3c06ec2 9332f7e cdf6731 02bafb6 f93c703 9332f7e d78fa13 726a7dd 749f56d 9332f7e 7c8d169 749f56d 9332f7e 749f56d 9332f7e 749f56d 9332f7e cdf6731 38b8d8b 9332f7e 50c02b0 cdf6731 9332f7e cdf6731 9332f7e 38b8d8b 749f56d 38b8d8b 9332f7e cdf6731 9332f7e cdf6731 9332f7e 3c06ec2 9332f7e 1ab7e62 9332f7e 02bafb6 |
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 |
import gradio as gr
from transformers import pipeline
import re
import os
from huggingface_hub import login
# โ
Authenticate using HF token stored in secret
login(token=os.environ.get("HUGGINGFACEHUB_API_TOKEN"))
# โ
Load Hugging Face summarization/chat model
summarizer = pipeline("text-generation", model="mistralai/Mistral-7B-Instruct-v0.1")
# โ
Highlight matching and find missing keywords
from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS
def compare_keywords(resume_text, job_desc):
resume_words = set(re.findall(r"\b\w{3,}\b", resume_text.lower())) - ENGLISH_STOP_WORDS
job_words = set(re.findall(r"\b\w{3,}\b", job_desc.lower())) - ENGLISH_STOP_WORDS
matched = resume_words & job_words
missing = job_words - resume_words
return matched, missing
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
# ๐ Use LLM to extract missing keywords contextually from JD
def extract_missing_keywords_with_llm(job_desc, resume_text):
prompt = f"""
You are an expert resume evaluator.
Given the job description and the resume, identify important skills, tools, and concepts in the job description that are missing or weakly represented in the resume.
List only the missing or insufficiently addressed keywords in bullet format.
Job Description:
{job_desc}
Resume:
{resume_text}
"""
result = summarizer(prompt, max_new_tokens=300, do_sample=True, temperature=0.7)[0]['generated_text']
return result.strip()
# ๐ Prompt for dynamic section classification and feedback
def build_dynamic_prompt(job_desc, resume_text, analyze_with_jd):
prompt = f"""
You are an expert resume analyst.
Classify the content of the resume into meaningful categories based on the text (e.g., Technical Skills, Soft Skills, Certifications, Projects, Work Experience, Education, Personal Information).
You do not need a fixed list of section namesโchoose the most suitable ones based on the content.
Then:
- For each section, summarize its contents.
- If a job description is provided, compare each section against it.
- Highlight missing or weak areas relevant to the job.
- Provide smart, actionable suggestions to improve each section.
- Output in structured Markdown with headings for each section.
"""
if analyze_with_jd and job_desc:
prompt += f"\nJob Description:\n{job_desc}\n"
prompt += f"\nResume:\n{resume_text}"
return prompt
# ๐ง Function to call Hugging Face model and get structured resume feedback
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:
response = summarizer(user_prompt, max_new_tokens=768, do_sample=True, temperature=0.7)[0]['generated_text']
cleaned = re.sub(rf".*?{re.escape(resume_text)}", "", response, flags=re.DOTALL).strip()
if analyze_with_jd and job_desc:
matched, _ = 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\n\n{highlighted_resume}\n\n---\n**โ
Matched Keywords:** {', '.join(sorted(matched)) or 'None'}\n\n**โ LLM-Inferred Missing Keywords:**\n{llm_missing_keywords}\n\n---\n{cleaned}"
return cleaned
except Exception as e:
return f"โ Error: {str(e)}"
# ๐๏ธ Gradio UI
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...")
with gr.Column():
output_analysis = gr.Markdown(label="Resume Analysis and Suggestions")
resume_text.change(fn=analyze_resume, inputs=[job_desc, resume_text, analyze_checkbox], outputs=output_analysis)
job_desc.change(fn=analyze_resume, inputs=[job_desc, resume_text, analyze_checkbox], outputs=output_analysis)
return demo
if __name__ == '__main__':
create_ui().launch() |