Skip to content

Commit 5467367

Browse files
committed
feat: resume analysis
1 parent 95d5e9e commit 5467367

File tree

3 files changed

+148
-9
lines changed

3 files changed

+148
-9
lines changed

code/app.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import json
22
import os
33
from flask import Flask, request, jsonify
4-
from pymongo import MongoClient
5-
from bson.objectid import ObjectId
4+
from pymongo.mongo_client import MongoClient
65
from modules.upload import upload_parse_resume
6+
from modules.evaluator import evaluate_resume
77

88
app = Flask(__name__)
99

@@ -13,20 +13,43 @@
1313

1414
# MongoDB
1515
client = MongoClient(config['MONGO_URI'])
16-
17-
db = client['resume_db']
18-
resume_collection = db['resumes']
16+
try:
17+
database = client.get_database("resume_db")
18+
resume_collection = database.get_collection("resumes")
19+
query = {"user_id": "333"}
20+
resume = resume_collection.find_one(query)
21+
print(resume)
22+
except Exception as e:
23+
raise Exception("Unable to find the document due to the following error: ", e)
1924

2025

2126
@app.route('/upload', methods=['POST'])
2227
def upload_resume():
2328
user_id = request.form.get('user_id')
2429
if not user_id:
2530
return jsonify({"error": "No user ID provided."}), 400
26-
# vector the resume text
31+
# Vector the resume text
2732
return upload_parse_resume(request, resume_collection)
2833

29-
# def evaluation():
34+
35+
@app.route('/resume_evaluate', methods=['POST'])
36+
def resume_evaluate():
37+
user_id = request.form.get('user_id')
38+
if not user_id:
39+
return jsonify({"error": "No user ID provided."}), 400
40+
41+
# Load resume from database
42+
resume = resume_collection.find_one({"user_id": user_id})
43+
if not resume:
44+
return jsonify({"error": "No resume found for this user."}), 404
45+
46+
resume_text = resume.get('resume_text', '')
47+
if not resume_text:
48+
return jsonify({"error": "Resume text is empty."}), 400
49+
50+
analysis_result = evaluate_resume(resume_text)
51+
52+
return jsonify({"analysis": analysis_result}), 200
3053

3154

3255
if __name__ == '__main__':

code/modules/evaluator.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
"""
2+
This module is responsible for evaluating resumes based on specified criteria.
3+
"""
4+
5+
import json
6+
import os
7+
from openai import OpenAI
8+
9+
# Load the OpenAI API key
10+
config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'configs', 'config.json')
11+
with open(config_path, 'r') as file:
12+
config = json.load(file)
13+
client = OpenAI(
14+
api_key=config['CHATGPT_API_KEY']
15+
)
16+
17+
# Define the scoring criteria and weights
18+
SCORING_CRITERIA = {
19+
'Relevance of Job Description': 30,
20+
'Achievements and Impact': 25,
21+
'Education and Certifications': 15,
22+
'Resume Structure and Presentation': 10,
23+
'Soft Skills': 10,
24+
'Consistency and Chronology': 10
25+
}
26+
27+
28+
def evaluate_resume(resume_text):
29+
"""
30+
Evaluate resumes by calling ChatGPT API
31+
"""
32+
try:
33+
prompt = f"""
34+
Please evaluate the following resume based on the criteria below, and structure your response according to the format provided:
35+
36+
Criteria:
37+
1. Relevance of Job Description (30%)
38+
2. Achievements and Impact (25%)
39+
3. Education and Certifications (15%)
40+
4. Resume Structure and Presentation (10%)
41+
5. Soft Skills (10%)
42+
6. Consistency and Chronology (10%)
43+
44+
The response should follow this format:
45+
46+
### Scores for each criteria:
47+
1. Relevance of Job Description: X/100
48+
2. Achievements and Impact: X/100
49+
3. Education and Certifications: X/100
50+
4. Resume Structure and Presentation: X/100
51+
5. Soft Skills: X/100
52+
6. Consistency and Chronology: X/100
53+
54+
### Weighted Total Score: Y/100
55+
56+
### Explanation for each criteria:
57+
1. Relevance of Job Description:
58+
[Explanation of the score]
59+
2. Achievements and Impact:
60+
[Explanation of the score]
61+
3. Education and Certifications:
62+
[Explanation of the score]
63+
4. Resume Structure and Presentation:
64+
[Explanation of the score]
65+
5. Soft Skills:
66+
[Explanation of the score]
67+
6. Consistency and Chronology:
68+
[Explanation of the score]
69+
70+
Resume: {resume_text}
71+
"""
72+
73+
# Call the evaluation API
74+
response = client.chat.completions.create(
75+
model='gpt-4o-mini',
76+
messages=[{'role': 'system', 'content': 'You are a professional resume evaluator.'},
77+
{'role': 'user', 'content': prompt}],
78+
max_tokens=500,
79+
temperature=0.7
80+
)
81+
82+
evaluation = response.choices[0].message.content
83+
return evaluation
84+
85+
except Exception as e:
86+
return f'Error evaluating resume: {str(e)}'
87+
88+
89+
def extract_scores_and_explanation(evaluation):
90+
"""
91+
Extracts the scores and explanations from the evaluation response.
92+
"""
93+
scores = {}
94+
explanation = ''
95+
lines = evaluation.split('\n')
96+
97+
# 6 criteria scores
98+
scores['Relevance of Job Description'] = int(lines[1].split(':')[1].strip().replace('/100', ''))
99+
scores['Achievements and Impact'] = int(lines[2].split(':')[1].strip().replace('/100', ''))
100+
scores['Education and Certifications'] = int(lines[3].split(':')[1].strip().replace('/100', ''))
101+
scores['Resume Structure and Presentation'] = int(lines[4].split(':')[1].strip().replace('/100', ''))
102+
scores['Soft Skills'] = int(lines[5].split(':')[1].strip().replace('/100', ''))
103+
scores['Consistency and Chronology'] = int(lines[6].split(':')[1].strip().replace('/100', ''))
104+
105+
# Weighted total score
106+
weighted_score = float(lines[8].split(':')[1].strip().replace('/100', ''))
107+
108+
# Explanation part
109+
explanation = '\n'.join(lines[11:])
110+
111+
return scores, weighted_score, explanation

code/preporcess/gpt_evalution.py renamed to code/preprocess/gpt_evalution.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44
and then outputs the scores and explanations to a new CSV file.
55
"""
66

7+
import json
8+
import os
79
import pandas as pd
810
from openai import OpenAI
911

10-
# OpenAI Key
12+
# Load the OpenAI API key
13+
config_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'configs', 'config.json')
14+
with open(config_path, 'r') as file:
15+
config = json.load(file)
1116
client = OpenAI(
12-
api_key='YOUR-GPT-API-KEY'
17+
api_key=config['CHATGPT_API_KEY']
1318
)
1419

1520
# Define the scoring criteria and weights

0 commit comments

Comments
 (0)