KhanOmerKhan commited on
Commit
a93e382
·
verified ·
1 Parent(s): 5bb17d4

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +253 -0
  2. requirements.txt +7 -0
app.py ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """Feedaltytics Recruiters Evaluation - FeedView.py
3
+
4
+ Automatically generated by Colab.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/10ERbz5c3Zuw50gSoCCDEuqP4wGsvdAaM
8
+ """
9
+
10
+ from docx import Document
11
+ import openai
12
+ import gradio as gr
13
+
14
+ # Set OpenAI API key
15
+ openai.api_key = 'sk-HPlLtHJKP7W3LXMh1-5lCzq9iJAepCFcm-6Ahvb4dmT3BlbkFJj2yl0vrpYL9D1YUHRGjk1RbraVK2Cy4zjYKiBPeooA'
16
+
17
+ # User credentials
18
+ USER_CREDENTIALS = {"admin": "password123"} # Replace with desired username/password pairs
19
+
20
+ # Function to extract text from DOCX files
21
+ def extract_text_from_docx(file):
22
+ doc = Document(file)
23
+ return '\n'.join([para.text for para in doc.paragraphs])
24
+
25
+ # Function to extract top 5 criteria and generate interview questions
26
+ def extract_criteria_and_questions(job_description):
27
+ try:
28
+ user_content = (
29
+ f"Job Description:\n{job_description}\n\n"
30
+ "Based on this job description, please identify the top 5 key attributes or skills required for this role. "
31
+ "For each attribute, provide 2-3 suggested interview questions that recruiters can use to assess candidates effectively."
32
+ )
33
+
34
+ response = openai.ChatCompletion.create(
35
+ model="gpt-3.5-turbo-16k",
36
+ messages=[
37
+ {
38
+ "role": "system",
39
+ "content": "You are an HR expert tasked with analyzing job descriptions and generating "
40
+ "key attributes to assess candidates, along with relevant interview questions. Be precise and concise."
41
+ },
42
+ {
43
+ "role": "user",
44
+ "content": user_content
45
+ }
46
+ ],
47
+ max_tokens=1000,
48
+ temperature=0.0,
49
+ top_p=1.0
50
+ )
51
+
52
+ result = response['choices'][0]['message']['content'].strip()
53
+ return result
54
+
55
+ except openai.error.OpenAIError as e:
56
+ return f"OpenAI API Error: {e}"
57
+ except Exception as e:
58
+ return f"Unexpected Error: {e}"
59
+
60
+ # Function to generate Recruiter's Report
61
+ def generate_recruiter_report(candidate_transcript, job_description, benchmark, criteria):
62
+ try:
63
+ user_content = (
64
+ f"Job Description:\n{job_description}\n\n"
65
+ f"Benchmark Transcript:\n{benchmark}\n\n"
66
+ f"Candidate Transcript:\n{candidate_transcript}\n\n"
67
+ f"Evaluation Criteria:\n{criteria}\n\n"
68
+ "Evaluate the candidate's overall performance against all criteria. Provide a detailed summary of their "
69
+ "strengths, areas for improvement, and an overall score based on the following grading scale:\n"
70
+ "Rate the candidate on a scale of 1-10 for each factor:\n"
71
+ "- **1**: Very poor, far below expectations, minimal skills or understanding.\n"
72
+ "- **2-3**: Below average, some understanding but lacking in key areas.\n"
73
+ "- **4-5**: Average, meets basic expectations with minimal distinction.\n"
74
+ "- **6-7**: Above average, solid performance with minor gaps.\n"
75
+ "- **8-9**: Strong, exceeds expectations with well-supported examples.\n"
76
+ "- **10**: Outstanding, exceptional performance with comprehensive examples.\n"
77
+ "Provide a total score out of 50 and a recommendation based on their suitability for the role."
78
+ )
79
+
80
+ response = openai.ChatCompletion.create(
81
+ model="gpt-3.5-turbo-16k",
82
+ messages=[
83
+ {
84
+ "role": "system",
85
+ "content": (
86
+ "You are a recruitment specialist evaluating candidates for a role. Use the provided criteria "
87
+ "and benchmarks to ensure consistency across evaluations. Keep the output professional."
88
+ )
89
+ },
90
+ {
91
+ "role": "user",
92
+ "content": user_content
93
+ }
94
+ ],
95
+ max_tokens=1500,
96
+ temperature=0.0,
97
+ top_p=1.0
98
+ )
99
+
100
+ report = response['choices'][0]['message']['content'].strip()
101
+ return report
102
+
103
+ except openai.error.OpenAIError as e:
104
+ return f"OpenAI API Error: {e}"
105
+ except Exception as e:
106
+ return f"Unexpected Error: {e}"
107
+
108
+ # Function to compare candidates and recommend the best fit
109
+ def compare_candidates_for_role(evaluation_reports, job_description):
110
+ try:
111
+ user_content = (
112
+ f"Job Description:\n{job_description}\n\n"
113
+ f"Recruiter's Evaluation Reports:\n{evaluation_reports}\n\n"
114
+ "Based on the provided job description and evaluation reports for multiple candidates, "
115
+ "analyze and compare their performance. Identify the candidate who best matches the role requirements, "
116
+ "and provide a summary of why this candidate is the best fit. Highlight any specific attributes or skills "
117
+ "that set them apart from others."
118
+ )
119
+
120
+ response = openai.ChatCompletion.create(
121
+ model="gpt-3.5-turbo-16k",
122
+ messages=[
123
+ {
124
+ "role": "system",
125
+ "content": (
126
+ "You are an expert recruiter tasked with analyzing evaluation reports and recommending the best "
127
+ "candidate for a role. Provide a detailed analysis with clear justification for your choice."
128
+ )
129
+ },
130
+ {
131
+ "role": "user",
132
+ "content": user_content
133
+ }
134
+ ],
135
+ max_tokens=1500,
136
+ temperature=0.0,
137
+ top_p=1.0
138
+ )
139
+
140
+ recommendation = response['choices'][0]['message']['content'].strip()
141
+ return recommendation
142
+
143
+ except openai.error.OpenAIError as e:
144
+ return f"OpenAI API Error: {e}"
145
+ except Exception as e:
146
+ return f"Unexpected Error: {e}"
147
+
148
+ # Function to process multiple transcripts
149
+ def process_transcripts(job_description_file, benchmark_file, candidate_files):
150
+ job_description = extract_text_from_docx(job_description_file)
151
+ benchmark = extract_text_from_docx(benchmark_file)
152
+ candidate_transcripts = [extract_text_from_docx(candidate_file) for candidate_file in candidate_files]
153
+
154
+ # Step 1: Extract top 5 criteria
155
+ criteria_and_questions = extract_criteria_and_questions(job_description)
156
+
157
+ # Step 2: Evaluate each candidate using all criteria
158
+ criteria = criteria_and_questions.split("\n\n")[:5] # Extract top criteria only
159
+ criteria_text = "\n\n".join(criteria)
160
+
161
+ all_reports = []
162
+ individual_reports = {}
163
+
164
+ for i, transcript in enumerate(candidate_transcripts):
165
+ report = generate_recruiter_report(transcript, job_description, benchmark, criteria_text)
166
+ all_reports.append(f"--- Candidate {i + 1} ---\n{report}\n")
167
+ individual_reports[f"candidate_{i + 1}"] = report
168
+
169
+ # Step 3: Compare candidates and recommend the best fit
170
+ comparison_report = compare_candidates_for_role("\n".join(all_reports), job_description)
171
+
172
+ return criteria_and_questions, "\n".join(all_reports), individual_reports, comparison_report
173
+
174
+ # Gradio interface setup
175
+ def main():
176
+ with gr.Blocks(css="""
177
+ #company-logo img {
178
+ width: 150px;
179
+ height: auto;
180
+ margin: 0 auto;
181
+ display: block;
182
+ }
183
+ """) as interface:
184
+ username = gr.Textbox(label="Username")
185
+ password = gr.Textbox(label="Password", type="password")
186
+ login_button = gr.Button("Login")
187
+ auth_status = gr.Textbox(label="Login Status", interactive=False)
188
+
189
+ with gr.Group(visible=False) as app_interface:
190
+ gr.Image(
191
+ value="https://drive.google.com/uc?id=1tgTSBVCm6gvg6EGEsgHsjsqyiGefxqHP",
192
+ show_label=False,
193
+ elem_id="company-logo"
194
+ )
195
+ gr.Markdown("### Recruiter's Evaluation Tool")
196
+
197
+ mode = gr.Radio(choices=["Generate Criteria", "Evaluate Candidates"], label="Choose Mode")
198
+
199
+ job_description_file = gr.File(label="Job Description (.docx)")
200
+
201
+ # Criteria Generation Outputs
202
+ criteria_output = gr.Textbox(label="Generated Criteria", lines=15)
203
+
204
+ # Candidate Evaluation Inputs and Outputs
205
+ benchmark_file = gr.File(label="Benchmark Transcript (.docx)")
206
+ candidate_files = gr.File(label="Candidate Transcripts (.docx)", file_count="multiple")
207
+ recruiter_output = gr.Textbox(label="Evaluation Reports", lines=30)
208
+ comparison_output = gr.Textbox(label="Best Fit Recommendation", lines=10)
209
+
210
+ def generate_criteria(job_description_file):
211
+ job_description = extract_text_from_docx(job_description_file)
212
+ return extract_criteria_and_questions(job_description)
213
+
214
+ def evaluate_candidates(job_description_file, benchmark_file, candidate_files):
215
+ _, reports, _, comparison = process_transcripts(job_description_file, benchmark_file, candidate_files)
216
+ return reports, comparison
217
+
218
+ mode.change(
219
+ lambda x: gr.update(visible=(x == "Generate Criteria")),
220
+ inputs=[mode],
221
+ outputs=[criteria_output]
222
+ )
223
+
224
+ # Generate Criteria
225
+ gr.Button("Generate Criteria").click(
226
+ generate_criteria,
227
+ inputs=[job_description_file],
228
+ outputs=[criteria_output]
229
+ )
230
+
231
+ # Evaluate Candidates
232
+ gr.Button("Evaluate Candidates").click(
233
+ evaluate_candidates,
234
+ inputs=[job_description_file, benchmark_file, candidate_files],
235
+ outputs=[recruiter_output, comparison_output]
236
+ )
237
+
238
+ def authenticate(username_value, password_value):
239
+ if username_value in USER_CREDENTIALS and USER_CREDENTIALS[username_value] == password_value:
240
+ return gr.update(visible=True), "Login Successful!"
241
+ else:
242
+ return gr.update(visible=False), "Login Failed. Please check your credentials."
243
+
244
+ login_button.click(
245
+ authenticate,
246
+ inputs=[username, password],
247
+ outputs=[app_interface, auth_status]
248
+ )
249
+
250
+ interface.launch()
251
+
252
+ if __name__ == "__main__":
253
+ main()
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ openai==0.28
2
+ gradio==3.11
3
+ python-docx
4
+ bcrypt
5
+ PyPDF2
6
+ httpx==0.23.0
7
+ httpcore==0.15.0