muhammadyousif commited on
Commit
cea0119
·
verified ·
1 Parent(s): d85f24c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -121
app.py CHANGED
@@ -68,6 +68,7 @@ INTERVIEW_QUESTIONS_INSTRUCTIONS = """
68
  </div>
69
  """
70
 
 
71
  COVER_LETTER_DISCLAIMER = """
72
  <p style="font-style: italic; color: #cccccc; background-color: #000000; padding: 10px; border-radius: 5px;">
73
  Disclaimer: This cover letter is generated based on the provided job description and resume.
@@ -85,13 +86,11 @@ They should be reviewed and adjusted to better fit the specific role, company cu
85
  TITLE = "<h1>📄 ATS Resume Analyzer 📄</h1>"
86
  PLACEHOLDER = "Chat with AI about your resume and job descriptions..."
87
 
88
- # ---------------- File parsers ----------------
89
-
90
  def extract_text_from_pdf(pdf_file):
91
  reader = PdfReader(pdf_file)
92
  text = ""
93
  for page in reader.pages:
94
- text += page.extract_text() or ""
95
  return text
96
 
97
  def extract_text_from_docx(docx_file):
@@ -101,8 +100,6 @@ def extract_text_from_docx(docx_file):
101
  text += para.text + "\n"
102
  return text
103
 
104
- # ---------------- Groq chat helper ----------------
105
-
106
  def generate_response(message: str, system_prompt: str, temperature: float, max_tokens: int):
107
  conversation = [
108
  {"role": "system", "content": system_prompt},
@@ -110,7 +107,7 @@ def generate_response(message: str, system_prompt: str, temperature: float, max_
110
  ]
111
 
112
  response = client.chat.completions.create(
113
- model="llama-3.1-8b-instant",
114
  messages=conversation,
115
  temperature=temperature,
116
  max_tokens=max_tokens,
@@ -119,93 +116,34 @@ def generate_response(message: str, system_prompt: str, temperature: float, max_
119
 
120
  return response.choices[0].message.content
121
 
122
- # ---------------- NEW: Recruiter-style scoring ----------------
123
-
124
  def analyze_resume_with_job_description(resume_text, job_description, temperature, max_tokens):
125
  prompt = f"""
126
- You are a senior technical recruiter with 12+ years hiring for AI, Data Science, Machine Learning,
127
- and Java development roles (10+ years experience required). Analyze this CV for a client role.
128
-
129
- Focus on:
130
- - Python/R, TensorFlow/PyTorch, scikit-learn
131
- - NLP/CV/LLMs
132
- - Java (Spring Boot, microservices)
133
- - AWS/GCP, APIs/databases
134
- - 10+ years hands-on experience
135
-
136
- CRITERIA (total 100):
137
- - SKILLS (40): ML frameworks (10), DS tools (8), Java advanced (10), cloud/DevOps (6), APIs/DB (6).
138
- - EDUCATION (20): 20 = MS/PhD CS/AI/ML, 15 = BS CS, 10 = strong certs (Google ML, AWS), 0 = irrelevant.
139
- - EXPERIENCE (40): 40 = 10+ yrs relevant with impact & leadership; scale linearly (e.g., 8 yrs = 32).
140
-
141
- TASK:
142
- 1) Extract key skills, education, roles, years, and major achievements.
143
- 2) Score skills/education/experience with brief justification.
144
- 3) Compute overall score (sum) and round.
145
- 4) Decide SHORTLIST = YES if overall ≥ 80 else NO.
146
- 5) Provide 3–5 bullet points of feedback.
147
-
148
- Return a clear **recruiter report** in this format:
149
-
150
- Overall Score: XX/100
151
- Shortlisted: YES or NO
152
-
153
- Skills Score: AA/40 – short justification
154
- Education Score: BB/20 – short justification
155
- Experience Score: CC/40 – short justification
156
-
157
- Feedback:
158
- - point 1
159
- - point 2
160
- - point 3
161
- - point 4 (optional)
162
- - point 5 (optional)
163
-
164
- Then add a short summary (2–3 lines) for the hiring manager.
165
-
166
- Job Description:
167
- {job_description}
168
-
169
- Resume:
170
- {resume_text}
171
- """
172
- return generate_response(prompt, "You are an expert ATS recruiter and CV scorer.", temperature, max_tokens)
173
 
174
  def analyze_resume_without_job_description(resume_text, temperature, max_tokens):
175
  prompt = f"""
176
- You are a senior technical recruiter with 12+ years hiring for AI, Data Science, Machine Learning,
177
- and Java roles. Analyze this CV **without a specific JD**, but still score it for a generic
178
- AI/DS/ML/Java Senior Developer role.
179
-
180
- Use the same scoring:
181
-
182
- - Skills: 0–40
183
- - Education: 0–20
184
- - Experience: 0–40
185
- - Overall: 0–100, and SHORTLIST if ≥ 80.
 
 
186
 
187
- Return in this format:
188
-
189
- Overall Score: XX/100
190
- Shortlisted: YES or NO
191
-
192
- Skills Score: AA/40 – short justification
193
- Education Score: BB/20 – short justification
194
- Experience Score: CC/40 – short justification
195
-
196
- Feedback:
197
- - point 1
198
- - point 2
199
- - point 3
200
- - point 4 (optional)
201
- - point 5 (optional)
202
-
203
- Then a 2–3 line summary for the hiring manager.
204
-
205
- Resume:
206
- {resume_text}
207
- """
208
- return generate_response(prompt, "You are an expert ATS recruiter and CV scorer.", temperature, max_tokens)
209
 
210
  def analyze_resume(resume_text, job_description, with_job_description, temperature, max_tokens):
211
  if with_job_description:
@@ -213,52 +151,43 @@ def analyze_resume(resume_text, job_description, with_job_description, temperatu
213
  else:
214
  return analyze_resume_without_job_description(resume_text, temperature, max_tokens)
215
 
216
- # ---------------- Other existing features (rephraser, CL, IQ) ----------------
217
 
218
  def rephrase_text(text, temperature, max_tokens):
219
  prompt = f"""
220
- Please rephrase the following text according to ATS standards, including quantifiable measures and
221
- improvements where possible. Maintain precise and concise points that pass ATS screening.
222
-
223
- Original Text:
224
- {text}
225
- """
226
  return generate_response(prompt, "You are an expert in rephrasing content for ATS optimization.", temperature, max_tokens)
227
 
228
  def clear_conversation():
229
  return [], None
230
 
 
231
  def generate_cover_letter(resume_text, job_description, temperature, max_tokens):
232
  prompt = f"""
233
- Using the provided resume and job description, create a compelling cover letter. The cover letter should:
234
- 1. Be tailored to the specific job and company.
235
- 2. Highlight relevant skills and experiences from the resume.
236
- 3. Show enthusiasm for the role and company.
237
- 4. Be professional and concise (about 250-300 words).
238
-
239
- Resume:
240
- {resume_text}
241
-
242
- Job Description:
243
- {job_description}
244
- """
245
  return generate_response(prompt, "You are an expert in writing tailored cover letters.", temperature, max_tokens)
246
 
247
  def generate_interview_questions(job_description, temperature, max_tokens):
248
  prompt = f"""
249
- Based on the following job description, generate a list of 10 probable interview questions. Include a mix of:
250
- 1. Role-specific technical questions (if applicable)
251
- 2. Behavioral questions related to the required skills
252
- 3. Questions about the candidate's experience and background
253
- 4. Questions to assess cultural fit
254
-
255
- Job Description:
256
- {job_description}
257
- """
258
  return generate_response(prompt, "You are an expert in creating relevant interview questions based on job descriptions.", temperature, max_tokens)
259
 
260
- # ---------------- Gradio UI ----------------
261
-
262
  with gr.Blocks(css=CSS, theme="Nymbo/Nymbo_Theme") as demo:
263
  gr.HTML(TITLE)
264
 
@@ -301,11 +230,11 @@ with gr.Blocks(css=CSS, theme="Nymbo/Nymbo_Theme") as demo:
301
  minimum=0, maximum=1, step=0.1, value=0.5, label="Temperature",
302
  )
303
  max_tokens = gr.Slider(
304
- minimum=50, maximum=1024, step=1, value=512, label="Max tokens",
305
  )
306
 
307
- def update_job_description_visibility(with_job_description_val):
308
- return gr.update(visible=with_job_description_val)
309
 
310
  with_job_description.change(
311
  update_job_description_visibility,
@@ -351,4 +280,4 @@ with gr.Blocks(css=CSS, theme="Nymbo/Nymbo_Theme") as demo:
351
  gr.HTML(FOOTER_TEXT)
352
 
353
  if __name__ == "__main__":
354
- demo.launch()
 
68
  </div>
69
  """
70
 
71
+ # Also update the disclaimer styles to match
72
  COVER_LETTER_DISCLAIMER = """
73
  <p style="font-style: italic; color: #cccccc; background-color: #000000; padding: 10px; border-radius: 5px;">
74
  Disclaimer: This cover letter is generated based on the provided job description and resume.
 
86
  TITLE = "<h1>📄 ATS Resume Analyzer 📄</h1>"
87
  PLACEHOLDER = "Chat with AI about your resume and job descriptions..."
88
 
 
 
89
  def extract_text_from_pdf(pdf_file):
90
  reader = PdfReader(pdf_file)
91
  text = ""
92
  for page in reader.pages:
93
+ text += page.extract_text()
94
  return text
95
 
96
  def extract_text_from_docx(docx_file):
 
100
  text += para.text + "\n"
101
  return text
102
 
 
 
103
  def generate_response(message: str, system_prompt: str, temperature: float, max_tokens: int):
104
  conversation = [
105
  {"role": "system", "content": system_prompt},
 
107
  ]
108
 
109
  response = client.chat.completions.create(
110
+ model="llama-3.1-8B-Instant",
111
  messages=conversation,
112
  temperature=temperature,
113
  max_tokens=max_tokens,
 
116
 
117
  return response.choices[0].message.content
118
 
119
+
 
120
  def analyze_resume_with_job_description(resume_text, job_description, temperature, max_tokens):
121
  prompt = f"""
122
+ Please analyze the following resume in the context of the job description provided. Strictly check every single line in the job description and analyze the resume for exact matches. Maintain high ATS standards and give scores only to the correct matches. Focus on missing core skills and soft skills. Provide the following details:
123
+ 1. The match percentage of the resume to the job description.
124
+ 2. A list of missing keywords.
125
+ 3. Final thoughts on the resume's overall match with the job description in 3 lines.
126
+ 4. Recommendations on how to add the missing keywords and improve the resume in 3-4 points with examples.
127
+ Job Description: {job_description}
128
+ Resume: {resume_text}
129
+ """
130
+ return generate_response(prompt, "You are an expert ATS resume analyzer.", temperature, max_tokens)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
  def analyze_resume_without_job_description(resume_text, temperature, max_tokens):
133
  prompt = f"""
134
+ Please analyze the following resume without a specific job description. Provide the following details:
135
+ 1. An overall score out of 10 for the resume.
136
+ 2. Suggestions for improvements based on the following criteria:
137
+ - Impact (quantification, repetition, verb usage, tenses, responsibilities, spelling & consistency)
138
+ - Brevity (length, bullet points, filler words)
139
+ - Style (buzzwords, dates, contact details, personal pronouns, active voice, consistency)
140
+ - Sections (summary, education, skills, unnecessary sections)
141
+ 3. A cumulative assessment of all the above fields.
142
+ 4. Recommendations for improving the resume in 3-4 points with examples.
143
+ Resume: {resume_text}
144
+ """
145
+ return generate_response(prompt, "You are an expert ATS resume analyzer.", temperature, max_tokens)
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
  def analyze_resume(resume_text, job_description, with_job_description, temperature, max_tokens):
149
  if with_job_description:
 
151
  else:
152
  return analyze_resume_without_job_description(resume_text, temperature, max_tokens)
153
 
154
+
155
 
156
  def rephrase_text(text, temperature, max_tokens):
157
  prompt = f"""
158
+ Please rephrase the following text according to ATS standards, including quantifiable measures and improvements where possible. Maintain precise and concise points which will pass ATS screening:
159
+ Original Text: {text}
160
+ """
 
 
 
161
  return generate_response(prompt, "You are an expert in rephrasing content for ATS optimization.", temperature, max_tokens)
162
 
163
  def clear_conversation():
164
  return [], None
165
 
166
+
167
  def generate_cover_letter(resume_text, job_description, temperature, max_tokens):
168
  prompt = f"""
169
+ Using the provided resume and job description, create a compelling cover letter. The cover letter should:
170
+ 1. Be tailored to the specific job and company.
171
+ 2. Highlight relevant skills and experiences from the resume.
172
+ 3. Show enthusiasm for the role and company.
173
+ 4. Be professional and concise (about 250-300 words).
174
+ Resume: {resume_text}
175
+ Job Description: {job_description}
176
+ """
 
 
 
 
177
  return generate_response(prompt, "You are an expert in writing tailored cover letters.", temperature, max_tokens)
178
 
179
  def generate_interview_questions(job_description, temperature, max_tokens):
180
  prompt = f"""
181
+ Based on the following job description, generate a list of 10 probable interview questions. Include a mix of:
182
+ 1. Role-specific technical questions (if applicable)
183
+ 2. Behavioral questions related to the required skills
184
+ 3. Questions about the candidate's experience and background
185
+ 4. Questions to assess cultural fit
186
+ Ensure the questions are tailored to the specific job role and requirements.
187
+ Job Description: {job_description}
188
+ """
 
189
  return generate_response(prompt, "You are an expert in creating relevant interview questions based on job descriptions.", temperature, max_tokens)
190
 
 
 
191
  with gr.Blocks(css=CSS, theme="Nymbo/Nymbo_Theme") as demo:
192
  gr.HTML(TITLE)
193
 
 
230
  minimum=0, maximum=1, step=0.1, value=0.5, label="Temperature",
231
  )
232
  max_tokens = gr.Slider(
233
+ minimum=50, maximum=1024, step=1, value=1024, label="Max tokens",
234
  )
235
 
236
+ def update_job_description_visibility(with_job_description):
237
+ return gr.update(visible=with_job_description)
238
 
239
  with_job_description.change(
240
  update_job_description_visibility,
 
280
  gr.HTML(FOOTER_TEXT)
281
 
282
  if __name__ == "__main__":
283
+ demo.launch()