-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathresume_parser.py
More file actions
329 lines (261 loc) · 10.4 KB
/
Copy pathresume_parser.py
File metadata and controls
329 lines (261 loc) · 10.4 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
import os
import time
from pathlib import Path
from dotenv import load_dotenv
from groq import Groq
from pydantic import BaseModel, Field
load_dotenv()
my_api_key=os.getenv("GROQ_API_KEY")
if not my_api_key:
raise ValueError("No API key found")
client=Groq(api_key=my_api_key)
model = "llama-3.3-70b-versatile"
job_description="""
Description
Do you want to solve real customer problems through innovative technology? Do you enjoy working on scalable services in a collaborative team environment? Do you want to see your code directly impact millions of customers worldwide?
At Amazon, we hire the best minds in technology to innovate and build on behalf of our customers. Customer obsession is part of our company DNA, which has made us one of the world's most beloved brands.
Our Software Development Engineers (SDEs) use modern technology to solve complex problems while seeing their work's impact first-hand. The challenges SDEs solve at Amazon are meaningful and influence millions of customers, sellers, and products globally. We seek individuals passionate about creating new products, features, and services while managing ambiguity in an environment where development cycles are measured in weeks, not years.
At Amazon, we believe in ownership at every level. As an SDE-I, you'll own the entire lifecycle of your code - from design through deployment and ongoing operations. This ownership mindset, combined with our commitment to operational excellence, ensures we deliver the highest quality solutions for our customers.
We're looking for curious minds who think big and want to define tomorrow's technology. At Amazon, you'll grow into the high-impact engineer you know you can be, supported by a culture of learning and mentorship. Every day brings exciting new challenges and opportunities for personal growth.
Key job responsibilities
• Collaborate and communicate effectively with experienced cross-disciplinary Amazonians to design, build, and operate innovative products and services that delight our customers, while participating in technical discussions to drive solutions forward.
• Design and develop scalable solutions using cloud-native architectures and microservices in a large distributed computing environment.
• Participate in code reviews and contribute to technical documentation.
• Build and maintain resilient distributed systems that are scalable, fault-tolerant, and cost-effective.
• Leverage and contribute to the development of GenAI and AI-powered tools to enhance development productivity while staying current with emerging technologies.
• Write clean, maintainable code following best practices and design patterns.
• Work in an agile environment practicing CI/CD principles while participating in operational responsibilities including on-call duties.
• Demonstrate operational excellence through monitoring, troubleshooting, and resolving production issues.
Basic Qualifications
- Experience with at least one general-purpose programming language such as Java, Python, C++, C#, Go, Rust, or TypeScript
- Experience with data structure implementation, basic algorithm development, and/or object-oriented design principles
- Currently has, or is in the process of obtaining a bachelor’s degree in Computer Science, Computer Engineering, Data Science, Information Systems, or related STEM fields
- Must be 18 years of age of older
Preferred Qualifications
- Experience from previous technical internship(s) or demonstrated project experience
- Experience with one or more of the following: AI tools for development productivity, Cloud platforms (preferably AWS), Database systems (SQL and NoSQL), Contributing to open-source projects, Version control systems, Debugging and troubleshooting complex systems
- Demonstrated ability to learn and adapt to new technologies quickly
- Basic understanding of software development lifecycle (SDLC)
- Strong problem-solving and analytical skills
- Excellent written and verbal communication skills
"""
class JobD(BaseModel):
role: str
required_skills: list[str]
preferred_skills: list[str]
minimum_experience: float | None
education_requirements: list[str]
responsibilities: list[str]
jobd_schema = JobD.model_json_schema()
system_prompt = f"""
You are an expert HR assistant.
Your job is to analyze job descriptions and extract
structured information from them.
Return ONLY valid JSON matching this schema:
{jobd_schema}
IMPORTANT:
Do NOT return the schema itself.
Do NOT return fields like "properties", "title" or "type".
Fill the schema with actual information extracted from the job description.
If minimum experience is not mentioned, return null.
If information for a list is missing, return an empty list.
Do not invent information.
"""
user_prompt = f"""
Analyze the following job description:
{job_description}
"""
message_system={
"role" : "system",
"content" : system_prompt
}
message_user={
"role" : "user",
"content" : user_prompt
}
response_format={
"type" : "json_object"
}
messages=[message_system, message_user]
response=client.chat.completions.create(model=model, messages=messages, response_format=response_format)
answer=response.choices[0].message.content
raw_json=answer
# print(raw_json)
import json
job_data=json.loads(raw_json)
job = JobD(**job_data)
print(job.minimum_experience)
print(job.education_requirements)
#parse real
class MatchResult(BaseModel):
score: float
details: dict
class Experience(BaseModel):
company: str | None = None
role: str | None = None
duration: str | None = None
description: str | None = None
skills_used: list[str] = []
class Resume(BaseModel):
name: str | None = None
email: str | None = None
phone: str | None = None
total_experience_years: float | None = None
skills: list[str] = []
experiences: list[Experience] = []
education: list[str] = []
projects: list[str] = []
certifications: list[str] = []
resume_schema = Resume.model_json_schema()
def final_score(job,resume):
match_schema = MatchResult.model_json_schema()
prompt = f"""
You are an HR recruiter.
Compare the candidate's resume with the job description.
JOB DESCRIPTION:
{job.model_dump_json(indent=2)}
CANDIDATE RESUME:
{resume.model_dump_json(indent=2)}
Return JSON matching this schema:
{match_schema}
Give me:
1. Candidate name
2. Matching skills
3. Missing important skills
4. Whether experience requirement is met
5. Overall match percentage from 0 to 100
6. A short final verdict
Keep the response concise and easy to read.
"""
message={
"role": "user",
"content" : prompt
}
messages=[message]
response_format={
"type": "json_object"
}
response = client.chat.completions.create(model=model, messages=messages, response_format=response_format)
data = json.loads(response.choices[0].message.content)
return MatchResult(**data)
def parse_resume(resume_text):
system_prompt = f"""
You are an expert resume parser.
Extract information from the resume based on its meaning,
not only based on exact section headings.
Different resumes may use different headings.
For example:
- Experience
- Professional Experience
- Work History
- Employment
- Internships
These may all contain relevant experience.
Skills may also appear in the skills section, work experience,
internships or projects.
Return ONLY valid JSON matching this schema:
{resume_schema}
Important rules:
1. Do not invent information.
2. If a value is not available, return null.
3. If a list has no information, return an empty list.
4. Include internships inside experiences.
5. Extract skills mentioned across the entire resume.
"""
user_prompt = f"""
Parse the following resume:
{resume_text}
"""
message_system={
"role" : "system",
"content" : system_prompt
}
message_user={
"role" : "user",
"content" : user_prompt
}
messages=[message_system, message_user]
response_format={
"type": "json_object"
}
response=client.chat.completions.create(model=model, messages=messages, response_format=response_format)
raw_output = response.choices[0].message.content
data = json.loads(raw_output)
resume = Resume(**data)
return resume
from pypdf import PdfReader
from docx import Document
def read_pdf(file_path):
reader = PdfReader(file_path)
text = ""
for page in reader.pages:
page_text = page.extract_text()
if page_text:
text += page_text + "\n"
return text
def read_docx(file_path):
document = Document(file_path)
text = ""
for paragraph in document.paragraphs:
if paragraph.text.strip():
text += paragraph.text + "\n"
for table in document.tables:
for row in table.rows:
for cell in row.cells:
if cell.text.strip():
text += cell.text + "\n"
return text
def read_resume(file_path):
if file_path.suffix.lower() == ".pdf":
return read_pdf(file_path)
elif file_path.suffix.lower() == ".docx":
return read_docx(file_path)
else:
return None
# lets do it now
resume_folder = Path("resumes")
all_results=[]
for file_path in resume_folder.iterdir():
#C:\Users\Pratyush\padho_with_pratyush\week1\day5\resumes\abhay resume new - Abhay Singh.pdf
if file_path.suffix.lower() not in [".pdf", ".docx"]:
continue
print("\nProcessing:", file_path.name)
resume_text = read_resume(file_path)
parsed_resume=parse_resume(resume_text) # llm call1
time.sleep(5)
result = final_score(job, parsed_resume) #llm caLL2
#score and details
#acount chtgpt
# request bhejna shhur krega millions
#chattgot server jam ho jayega
time.sleep(5)
print("Score:", result.score)
all_results.append({
"name": parsed_resume.name,
"score": result.score,
"details": result.details
})
all_results.sort(
key=lambda candidate: candidate["score"],
reverse=True
)
top_2 = all_results[:2]
worst_2 = all_results[-2:]
print("TOP 2 CANDIDATES")
for candidate in top_2:
print(
candidate["name"],
"-",
candidate["score"],
"%"
)
print(candidate["details"])
print("LOWEST 2 CANDIDATES")
for candidate in worst_2:
print(
candidate["name"],
"-",
candidate["score"],
"%"
)
print(candidate["details"])