ShubhamD95 commited on
Commit
f6c9488
Β·
verified Β·
1 Parent(s): f8fa1b3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -11
app.py CHANGED
@@ -3,30 +3,42 @@ from transformers import pipeline
3
  import re
4
  import os
5
  from huggingface_hub import login
 
 
6
 
7
- # βœ… Authenticate using HF token stored in secret
8
  login(token=os.environ.get("HUGGINGFACEHUB_API_TOKEN"))
9
 
10
- # βœ… Use a lightweight instruction-tuned model compatible with CPU
11
  summarizer = pipeline("text2text-generation", model="declare-lab/flan-alpaca-base")
12
 
13
- # βœ… Highlight matching and find missing keywords
14
- from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS
 
 
 
 
 
 
 
 
15
 
 
16
  def compare_keywords(resume_text, job_desc):
17
- resume_words = set(re.findall(r"\b\w{3,}\b", resume_text.lower())) - ENGLISH_STOP_WORDS
18
- job_words = set(re.findall(r"\b\w{3,}\b", job_desc.lower())) - ENGLISH_STOP_WORDS
19
  matched = resume_words & job_words
20
  missing = job_words - resume_words
21
  return matched, missing
22
 
 
23
  def highlight_keywords(resume_text, matched):
24
  highlighted = resume_text
25
  for word in sorted(matched, key=len, reverse=True):
26
  highlighted = re.sub(rf"\b({re.escape(word)})\b", r"**\1**", highlighted, flags=re.IGNORECASE)
27
  return highlighted
28
 
29
- # πŸ” Use LLM to extract missing keywords contextually from JD
30
  def extract_missing_keywords_with_llm(job_desc, resume_text):
31
  prompt = f"""
32
  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.
@@ -39,7 +51,7 @@ Only list the missing keywords as bullet points.
39
  result = summarizer(prompt, max_new_tokens=300, do_sample=True)[0]
40
  return result.get('generated_text', result.get('summary_text', str(result))).strip()
41
 
42
- # πŸ” Prompt for dynamic section classification and feedback
43
  def build_dynamic_prompt(job_desc, resume_text, analyze_with_jd):
44
  prompt = f"""
45
  Analyze the resume below and organize it into meaningful categories (e.g., Skills, Education, Work Experience, etc.).
@@ -52,7 +64,7 @@ Return structured Markdown with headers for each section and improvement suggest
52
  """
53
  return prompt
54
 
55
- # 🧠 Function to call Hugging Face model and get structured resume feedback
56
  def analyze_resume(job_desc, resume_text, analyze_with_jd):
57
  if not resume_text.strip():
58
  return "⚠️ Please paste your resume text."
@@ -62,16 +74,35 @@ def analyze_resume(job_desc, resume_text, analyze_with_jd):
62
  try:
63
  result = summarizer(user_prompt, max_new_tokens=512, do_sample=True)[0]
64
  response_text = result.get('generated_text', result.get('summary_text', str(result))).strip()
 
65
  if analyze_with_jd and job_desc:
66
  matched, missing = compare_keywords(resume_text, job_desc)
67
  highlighted_resume = highlight_keywords(resume_text, matched)
68
  llm_missing_keywords = extract_missing_keywords_with_llm(job_desc, resume_text)
69
- return f"### πŸ” Resume with Highlighted Matches\n\n{highlighted_resume}\n\n---\n**βœ… Matched Keywords (Basic Comparison):**\n{', '.join(sorted(matched)) or 'None'}\n\n**❌ Missing Keywords (Basic Comparison):**\n{', '.join(sorted(missing)) or 'None'}\n\n**πŸ€– LLM-Inferred Missing Keywords:**\n{llm_missing_keywords}\n\n---\n{response_text}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  return response_text
71
  except Exception as e:
72
  return f"❌ Error: {str(e)}"
73
 
74
- # πŸŽ›οΈ Gradio UI
75
  def create_ui():
76
  with gr.Blocks() as demo:
77
  with gr.Row():
 
3
  import re
4
  import os
5
  from huggingface_hub import login
6
+ import spacy
7
+ from sklearn.feature_extraction.text import ENGLISH_STOP_WORDS
8
 
9
+ # Authenticate with Hugging Face
10
  login(token=os.environ.get("HUGGINGFACEHUB_API_TOKEN"))
11
 
12
+ # Load summarization model
13
  summarizer = pipeline("text2text-generation", model="declare-lab/flan-alpaca-base")
14
 
15
+ # Load SpaCy English model
16
+ nlp = spacy.load("en_core_web_sm")
17
+
18
+ # πŸ” Use SpaCy to extract nouns and proper nouns (contextually relevant keywords)
19
+ def extract_relevant_keywords(text):
20
+ doc = nlp(text.lower())
21
+ return set(
22
+ token.text for token in doc
23
+ if token.pos_ in {"NOUN", "PROPN"} and not token.is_stop and len(token.text) > 2
24
+ )
25
 
26
+ # Compare keywords with semantic filtering
27
  def compare_keywords(resume_text, job_desc):
28
+ resume_words = extract_relevant_keywords(resume_text)
29
+ job_words = extract_relevant_keywords(job_desc)
30
  matched = resume_words & job_words
31
  missing = job_words - resume_words
32
  return matched, missing
33
 
34
+ # Highlight matched keywords in the resume
35
  def highlight_keywords(resume_text, matched):
36
  highlighted = resume_text
37
  for word in sorted(matched, key=len, reverse=True):
38
  highlighted = re.sub(rf"\b({re.escape(word)})\b", r"**\1**", highlighted, flags=re.IGNORECASE)
39
  return highlighted
40
 
41
+ # LLM-based missing keyword extraction
42
  def extract_missing_keywords_with_llm(job_desc, resume_text):
43
  prompt = f"""
44
  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.
 
51
  result = summarizer(prompt, max_new_tokens=300, do_sample=True)[0]
52
  return result.get('generated_text', result.get('summary_text', str(result))).strip()
53
 
54
+ # Resume improvement prompt
55
  def build_dynamic_prompt(job_desc, resume_text, analyze_with_jd):
56
  prompt = f"""
57
  Analyze the resume below and organize it into meaningful categories (e.g., Skills, Education, Work Experience, etc.).
 
64
  """
65
  return prompt
66
 
67
+ # Generate analysis result
68
  def analyze_resume(job_desc, resume_text, analyze_with_jd):
69
  if not resume_text.strip():
70
  return "⚠️ Please paste your resume text."
 
74
  try:
75
  result = summarizer(user_prompt, max_new_tokens=512, do_sample=True)[0]
76
  response_text = result.get('generated_text', result.get('summary_text', str(result))).strip()
77
+
78
  if analyze_with_jd and job_desc:
79
  matched, missing = compare_keywords(resume_text, job_desc)
80
  highlighted_resume = highlight_keywords(resume_text, matched)
81
  llm_missing_keywords = extract_missing_keywords_with_llm(job_desc, resume_text)
82
+
83
+ return f"""### πŸ” Resume with Highlighted Matches
84
+
85
+ {highlighted_resume}
86
+
87
+ ---
88
+
89
+ ** Matched Keywords (Semantic Comparison):**
90
+ {', '.join(sorted(matched)) or 'None'}
91
+
92
+ ** Missing Keywords (Semantic Comparison):**
93
+ {', '.join(sorted(missing)) or 'None'}
94
+
95
+ ** LLM-Inferred Missing Keywords:**
96
+ {llm_missing_keywords}
97
+
98
+ ---
99
+
100
+ {response_text}"""
101
  return response_text
102
  except Exception as e:
103
  return f"❌ Error: {str(e)}"
104
 
105
+ # Gradio Interface
106
  def create_ui():
107
  with gr.Blocks() as demo:
108
  with gr.Row():