ShubhamD95 commited on
Commit
b925d82
Β·
verified Β·
1 Parent(s): 6e31e76

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -44
app.py CHANGED
@@ -4,23 +4,26 @@ import re
4
  import os
5
  from huggingface_hub import login
6
  import spacy
 
7
 
8
- # Authenticate with Hugging Face token
9
  login(token=os.environ.get("HUGGINGFACEHUB_API_TOKEN"))
10
 
11
- # Load models
12
  summarizer = pipeline("text2text-generation", model="declare-lab/flan-alpaca-base")
 
 
13
  nlp = spacy.load("en_core_web_sm")
14
 
15
- # Extract contextually relevant keywords using spaCy
16
  def extract_relevant_keywords(text):
17
  doc = nlp(text.lower())
18
  return set(
19
- token.lemma_ for token in doc
20
  if token.pos_ in {"NOUN", "PROPN"} and not token.is_stop and len(token.text) > 2
21
  )
22
 
23
- # Compare resume and JD for keyword matches
24
  def compare_keywords(resume_text, job_desc):
25
  resume_words = extract_relevant_keywords(resume_text)
26
  job_words = extract_relevant_keywords(job_desc)
@@ -28,57 +31,40 @@ def compare_keywords(resume_text, job_desc):
28
  missing = job_words - resume_words
29
  return matched, missing
30
 
31
- # Highlight matched words in resume text
32
  def highlight_keywords(resume_text, matched):
33
  highlighted = resume_text
34
  for word in sorted(matched, key=len, reverse=True):
35
  highlighted = re.sub(rf"\b({re.escape(word)})\b", r"**\1**", highlighted, flags=re.IGNORECASE)
36
  return highlighted
37
 
38
- # LLM-based keyword extraction from JD
39
  def extract_missing_keywords_with_llm(job_desc, resume_text):
40
  prompt = f"""
41
  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.
42
- Only list the missing keywords as bullet points.
43
-
44
  Job Description:
45
  {job_desc}
46
-
47
  Resume:
48
  {resume_text}
 
49
  """
50
- result = summarizer(prompt, max_new_tokens=300, do_sample=False)[0]
51
- raw_text = result.get('generated_text', result.get('summary_text', str(result))).strip()
52
 
53
- # Clean and deduplicate
54
- lines = re.findall(r"-\s*(.+)", raw_text)
55
- cleaned = list({kw.strip().lower() for kw in lines if len(kw.strip()) > 2})
56
- return ', '.join(sorted(cleaned)) or "None"
57
-
58
- # Prompt builder for structured LLM resume analysis
59
  def build_dynamic_prompt(job_desc, resume_text, analyze_with_jd):
60
  prompt = f"""
61
- Act as a resume evaluator. Break the following resume into meaningful sections such as:
62
- - Technical Skills
63
- - Soft Skills
64
- - Education
65
- - Experience
66
- - Certifications
67
- - Projects (if present)
68
-
69
- Then, if a job description is provided, highlight what improvements are needed in each section to better align with the job role.
70
-
71
  Job Description:
72
  {job_desc if analyze_with_jd else '[None provided]'}
73
-
74
  Resume:
75
  {resume_text}
76
-
77
- Output your response in markdown format with section headings.
78
  """
79
  return prompt
80
 
81
- # Core analysis function
82
  def analyze_resume(job_desc, resume_text, analyze_with_jd):
83
  if not resume_text.strip():
84
  return "⚠️ Please paste your resume text."
@@ -86,7 +72,7 @@ def analyze_resume(job_desc, resume_text, analyze_with_jd):
86
  user_prompt = build_dynamic_prompt(job_desc, resume_text, analyze_with_jd)
87
 
88
  try:
89
- result = summarizer(user_prompt, max_new_tokens=512, do_sample=False)[0]
90
  response_text = result.get('generated_text', result.get('summary_text', str(result))).strip()
91
 
92
  if analyze_with_jd and job_desc:
@@ -95,28 +81,21 @@ def analyze_resume(job_desc, resume_text, analyze_with_jd):
95
  llm_missing_keywords = extract_missing_keywords_with_llm(job_desc, resume_text)
96
 
97
  return f"""### πŸ” Resume with Highlighted Matches
98
-
99
  {highlighted_resume}
100
-
101
  ---
102
-
103
- **βœ… Matched Keywords (Semantic Match):**
104
  {', '.join(sorted(matched)) or 'None'}
105
-
106
- **❌ Missing Keywords (Semantic Match):**
107
  {', '.join(sorted(missing)) or 'None'}
108
-
109
- **πŸ€– LLM-Inferred Missing Keywords:**
110
  {llm_missing_keywords}
111
-
112
  ---
113
-
114
  {response_text}"""
115
  return response_text
116
  except Exception as e:
117
  return f"❌ Error: {str(e)}"
118
 
119
- # Gradio interface
120
  def create_ui():
121
  with gr.Blocks() as demo:
122
  with gr.Row():
 
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)
 
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.
 
 
45
  Job Description:
46
  {job_desc}
 
47
  Resume:
48
  {resume_text}
49
+ Only list the missing keywords as bullet points.
50
  """
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.).
58
+ If a job description is provided, compare it against the resume and suggest improvements section by section.
 
 
 
 
 
 
 
 
59
  Job Description:
60
  {job_desc if analyze_with_jd else '[None provided]'}
 
61
  Resume:
62
  {resume_text}
63
+ Return structured Markdown with headers for each section and improvement suggestions.
 
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."
 
72
  user_prompt = build_dynamic_prompt(job_desc, resume_text, analyze_with_jd)
73
 
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:
 
81
  llm_missing_keywords = extract_missing_keywords_with_llm(job_desc, resume_text)
82
 
83
  return f"""### πŸ” Resume with Highlighted Matches
 
84
  {highlighted_resume}
 
85
  ---
86
+ ** Matched Keywords (Semantic Comparison):**
 
87
  {', '.join(sorted(matched)) or 'None'}
88
+ ** Missing Keywords (Semantic Comparison):**
 
89
  {', '.join(sorted(missing)) or 'None'}
90
+ ** LLM-Inferred Missing Keywords:**
 
91
  {llm_missing_keywords}
 
92
  ---
 
93
  {response_text}"""
94
  return response_text
95
  except Exception as e:
96
  return f"❌ Error: {str(e)}"
97
 
98
+ # Gradio Interface
99
  def create_ui():
100
  with gr.Blocks() as demo:
101
  with gr.Row():