File size: 16,268 Bytes
0a70db9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
from openai import OpenAI
from dotenv import load_dotenv
import os
import json
import pandas as pd
import fitz
from typing import List,Tuple
import streamlit as st
import numpy as np
import tiktoken
import tkinter as tk
from tkinter import filedialog, simpledialog
import re
load_dotenv()
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
HELICONE_API_KEY=os.getenv("HELICONE_API_KEY")
SysPromptDefault = "You are now in the role of an expert AI."

def response(message: object, model: object = "llama3-8b-8192", SysPrompt: object = SysPromptDefault, temperature: object = 0.2) -> object:
    """



    :rtype: object

    """
    client = OpenAI(
        api_key=GROQ_API_KEY,
        base_url="https://gateway.hconeai.com/openai/v1",
        default_headers={
            "Helicone-Auth": f"Bearer {HELICONE_API_KEY}",
            "Helicone-Target-Url": "https://api.groq.com"
        }
    )

    messages = [{"role": "system", "content": SysPrompt}, {"role": "user", "content": message}]
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        temperature=temperature,
        frequency_penalty=0.2,
    )
    return response.choices[0].message.content

def extract_content(pdf_content: bytes) -> List[str]:
    """

    Takes PDF (bytes) and returns a list of strings containing text from each page.

    """
    pdf_doc = fitz.open(stream=pdf_content, filetype="pdf")

    pages_content = []
    for page_number in range(pdf_doc.page_count):
        # Extracting text content
        page = pdf_doc.load_page(page_number)
        text_content = page.get_text("text").replace("\n", "\t")
        pages_content.append(text_content)

    pdf_doc.close()
    return pages_content

resume_prompt="""



**You are a professional resume analyst with extensive experience in parsing and evaluating candidate resumes for recruitment purposes. Your task is to analyze a given candidate's resume and extract specific information related to their recent qualifications, skills, work experience, and total professional experience. You have a keen eye for detail and a thorough understanding of how to present information in a structured format.**



**Objective:** Extract and structure relevant data from the RESUME in JSON format, focusing on the most recent qualifications, skills, work experience, and total professional experience.



**Instructions:**



1. **Qualification:**

   - Extract the most recent qualification of the candidate.

   - Ensure it is limited to professional certifications or advanced degrees (exclude schools and colleges).

   - Provide only the most recent qualification.



2. **Skills:**

   - List the candidate’s key skills relevant to their profession.

   - Include technical skills, soft skills, and any other professional competencies mentioned.



3. **Recent Experience:**

   - Identify and list the candidate’s most recent job experience.

   - For the recent experience, include:

     - **Role**: The job title or position held.

     - **Company**: The name of the company where the experience was gained.

     - **Experience Duration**: The total duration of the recent experience in years (in numerical format).

   - Summarize the projects undertaken in this role in 2 to 3 lines, highlighting the primary responsibilities and outcomes.



4. **Total Experience:**

   - Calculate the candidate’s total professional experience in years.

   - This includes all relevant work experiences, adding up the duration from each job listed on the resume.



5. **Output Format:**

   - Structure the extracted information in a JSON format with the following keys:

     - `recent_qualification`

     - `skills`

     - `recent_experience` which includes `role`, `company`, `experience_duration`, and `projects_summary`.

     - `total_experience`



**Sample JSON Output:**

```json

{

  "recent_qualification": "Project Management Professional (PMP) Certification",

  "skills": ["JavaScript", "Project Management", "Team Leadership", "Agile Methodologies", "Problem Solving"],

  "recent_experience": {

    "role": "Senior Project Manager",

    "company": "Tech Solutions Inc.",

    "experience_duration": 3,

    "projects_summary": "Managed a team of developers to deliver a web-based application, leading to a 20% increase in client satisfaction. Successfully implemented agile processes that improved project turnaround time by 15%."

  },

  "total_experience": 10

}

```



**Steps:**

1. Parse the resume and identify sections relevant to qualifications, skills, and work experience.

2. Extract the most recent professional qualification.

3. Compile a list of key skills mentioned.

4. Determine the most recent job experience, including the role, company, and duration.

5. Summarize the key projects and responsibilities undertaken in the recent role.

6. Calculate the total professional experience by adding up the duration of each job listed in the resume.

7. Format the extracted data into a structured JSON object as specified.



Take a deep breath and work on this problem step-by-step.

"""

jd_prompt="""



**You are an HR data analyst with expertise in extracting structured information from JOB_DESCRIPTION. You specialize in identifying key details such as job roles, requirements, qualifications, experience, and skill sets in a precise and systematic manner.**



**Objective:** Your task is to analyze the provided JOB_DESCRIPTION and extract the following details:

1. **Position/Role:** The name of the job position or role being advertised.

2. **Requirements for the Role:** Key responsibilities and tasks associated with the job.

3. **Qualifications:** The required educational background or certifications.

4. **Experience Required:** The number of years of experience required for the job, in numerical format.

5. **Skill Set:** The specific skills required for the job, including both technical and soft skills.



**Steps:**

1. **Identify the Position/Role:** Locate the title or primary name of the job being described. Extract this information as a string.

2. **Determine the Requirements for the Role:** List the main responsibilities and tasks expected from the candidate in a detailed manner.

3. **Extract Qualifications:** Identify the required educational background and certifications. Specify if any particular degree or certification is needed.

4. **Calculate the Experience Required:** Extract the number of years of professional experience required. If a range is provided, list the minimum and maximum years. If only a single value is mentioned, note that value.

5. **List the Skill Set:** Identify and list both technical and soft skills required for the role. Technical skills may include specific software or tools, while soft skills may include communication or teamwork abilities.



**Format the Output:** Return the extracted information in valid JSON format as shown below:



```json

{

  "position_role": "string",

  "requirements": [

    "string",

    "string",

    ...

  ],

  "qualifications": [

    "string",

    "string",

    ...

  ],

  "experience_required": {

    "min_years": number,

    "max_years": number

  },

  "skill_set": {

    "technical_skills": [

      "string",

      "string",

      ...

    ],

    "soft_skills": [

      "string",

      "string",

      ...

    ]

  }

}

```



**Example Output:**



```json

{

  "position_role": "Software Engineer",

  "requirements": [

    "Develop and maintain software applications",

    "Collaborate with cross-functional teams",

    "Write clean, scalable code"

  ],

  "qualifications": [

    "Bachelor's degree in Computer Science",

    "Proficiency in Java and Python"

  ],

  "experience_required": {

    "min_years": 2,

    "max_years": 5

  },

  "skill_set": {

    "technical_skills": [

      "Java",

      "Python",

      "SQL"

    ],

    "soft_skills": [

      "Team collaboration",

      "Problem-solving",

      "Effective communication"

    ]

  }

}

```



Please ensure all fields are accurately filled based on the job description. If any field is not applicable, leave it empty but maintain the JSON structure. If any value is indeterminate, use `null` for numbers and an empty string for strings.



**Take a deep breath and work on this problem step-by-step.**

"""

grading_prompt="""



**You are an expert in human resources and data analysis with over 15 years of experience in evaluating job descriptions and resumes. Your expertise includes matching job requirements with candidate qualifications and providing detailed feedback based on various parameters such as role fit, skillset, experience, and educational background.**



**Objective:**

You are to analyze a provided JOB_DESCRIPTION and a RESUME  provided by the user. Your task is to evaluate the match between the job requirements and the candidate's qualifications. The output should be in JSON format, highlighting the weightage, score, and reasoning for each category: role, skillset, experience, and educational qualifications.

Be conservative in assigning the score.

**Steps:**



1. **Input Texts:**

   - Extract the provided job description and resume from the input text.

   - Delimit each part using triple backticks for clarity.



2. **Identify Job Description Components:**

   - Parse the job description to extract:

     - **Role:** Identify the job title or primary role being advertised.

     - **Skillset:** List the specific skills required for the job, including technical, soft, and any specific software or tools.

     - **Experience:** Mention the years of experience or specific types of experience required.

     - **Educational Qualifications:** Note any required or preferred educational background, such as degrees or certifications.



3. **Identify Resume Components:**

   - Parse the resume to extract:

     - **Role:** Identify the current or most recent job title and any relevant past job titles.

     - **Skillset:** List the skills mentioned, including technical, soft, and specific software or tools.

     - **Experience:** Note the years of experience and the type of experience in various roles.

     - **Educational Qualifications:** List the educational background, including degrees and certifications.



4. **Matching Criteria:**

   - Compare each category from the job description with the corresponding category from the resume.

   - Evaluate the match and assign a weightage (e.g., 1 to 10) for each category based on relevance and completeness of match.

   - Provide a score (e.g., percentage) that reflects how well the candidate’s qualifications meet the job requirements.Follow a conservative approach in assigning the score.

   - Offer reasoning for each score, explaining how the candidate's qualifications align or diverge from the job requirements.



5. **Generate JSON Output:**

   - Structure the output in JSON format with the following keys:

     - **role_match**: { "weightage": X, "score": Y, "reasoning": "Detailed analysis" }

     - **skillset_match**: { "weightage": X, "score": Y, "reasoning": "Detailed analysis" }

     - **experience_match**: { "weightage": X, "score": Y, "reasoning": "Detailed analysis" }

     - **education_match**: { "weightage": X, "score": Y, "reasoning": "Detailed analysis" }

   - Ensure each key has a nested structure that clearly outlines the evaluation for each category.



6. **Final Summary:**

   - Summarize the overall match between the job description and the resume.

   - Provide an overall score and a brief narrative on the suitability of the candidate for the job role.



**Example JSON Output Structure:**

```json

{

  "role_match": {

    "weightage": 8,

    "score": 90,

    "reasoning": "The candidate's current and previous job titles align well with the role specified in the job description."

  },

  "skillset_match": {

    "weightage": 7,

    "score": 85,

    "reasoning": "The candidate possesses most of the required technical skills, with some minor gaps in specific tools."

  },

  "experience_match": {

    "weightage": 9,

    "score": 95,

    "reasoning": "The candidate has the required years of experience and relevant industry background."

  },

  "education_match": {

    "weightage": 6,

    "score": 80,

    "reasoning": "The candidate's educational background meets the requirements but lacks some preferred certifications."

  },

  "overall_score": 87.5,

  "summary": "The candidate is a strong match for the job role, with relevant experience and skills. The educational background is adequate, though additional certifications could enhance suitability."

}

```



Take a deep breath and work on this problem step-by-step."""


def extract_json(response_str):
    """Extract the JSON part from the response string and handle comments."""
    # Remove single-line comments (//) and multi-line comments (/* */)
    response_str = re.sub(r'//.*?\n|/\*.*?\*/', '', response_str, flags=re.DOTALL)

    match = re.search(r"\{.*}", response_str, re.DOTALL)
    if match:
        json_part = match.group()
        try:
            parsed_json = json.loads(json_part)  # Check if it's valid JSON
            return json_part
        except json.JSONDecodeError as e:
            print("Invalid JSON detected. Error:", e)
            print("JSON part:", json_part)
    else:
        print("No JSON part found in the response string.")
    return None

def identification(pdf_content):
    data = extract_content(pdf_content)
    print(data)
    model = "llama3-70b-8192"
    context = "\n\n".join(data)
    message = f"RESUME\n\n{context}\n\n"
    response_str = response(message=message, model=model, SysPrompt=resume_prompt, temperature=0)
    json_part = extract_json(response_str)
    return json_part


def classify_jd(job_description):
    model = "llama3-70b-8192"
    message = f"JOB_DESCRIPTION\n\n{job_description}\n\n"
    response_str = response(message=message, model=model, SysPrompt=jd_prompt, temperature=0)
    print(response_str)
    json_part = extract_json(response_str)
    return json_part

def grading(pdf_content,job_description):
    resume_str=identification(pdf_content)
    jd_str=classify_jd(job_description)
    print(jd_str)
    message = f"RESUME:\n\n{json.dumps(resume_str, indent=4)}\n\nJOB_DESCRIPTION:\n\n{json.dumps(jd_str,indent=4)}\n\n"
    model = "llama3-70b-8192"
    output_str = response(message=message, model=model, SysPrompt=grading_prompt, temperature=0)
    output=json.loads(extract_json(output_str))
    print(output)
    return output

def display_grading_results(grading_results):
    df = {
        "Criteria": [],
        "Score": [],
        "Weightage": [],
        "Reasoning": []
    }

    # Populate the dataframe
    for section, values in grading_results.items():
        if section != 'overall_score' and section != 'summary':
            df["Criteria"].append(section)
            df["Score"].append(values["score"])
            df["Weightage"].append(values["weightage"])
            df["Reasoning"].append(values["reasoning"])

    grading_df = pd.DataFrame(df)

    st.header("Grading Results")
    st.table(data=grading_df)
    st.subheader(f"Overall Score: {grading_results['overall_score']}")
    st.write(f"Summary: {grading_results['summary']}")


def main():
    st.title("Resume Matcher")

    # File uploader for PDF
    pdf_file = st.file_uploader("Upload PDF file", type=["pdf"])

    # Text area for job description input
    job_description = st.text_area("Enter Job Description", height=200)

    if st.button("Submit"):
        if pdf_file is not None and job_description:
            try:
                pdf_content = pdf_file.read()

                # Assuming grading function exists
                grades = grading(pdf_content, job_description)
                st.success(f"Grading completed successfully.")
                display_grading_results(grades)

            except Exception as e:
                st.error(f"An error occurred while processing the PDF: {e}")


if __name__ == "__main__":
    main()