safiaa02 commited on
Commit
5e6df1f
·
verified ·
1 Parent(s): 6aea49d

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +132 -0
app.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import openai
3
+ import os
4
+ from PyPDF2 import PdfReader
5
+ import docx2txt
6
+
7
+ # Load your API Key securely
8
+ openai.api_key = os.environ.get("OPENAI_API_KEY")
9
+
10
+ # Helper function to read PDF
11
+ def read_pdf(file_obj):
12
+ reader = PdfReader(file_obj)
13
+ text = ""
14
+ for page in reader.pages:
15
+ text += page.extract_text() + "\n"
16
+ return text
17
+
18
+ # Helper function to read DOCX
19
+ def read_docx(file_obj):
20
+ return docx2txt.process(file_obj)
21
+
22
+ # Main SmartHire Agent function
23
+ def analyze_resumes(resume_files, job_description, min_years_exp=0):
24
+ if not resume_files or not job_description:
25
+ return "⚠️ Please upload resumes and provide a job description."
26
+
27
+ resumes = []
28
+ for file in resume_files:
29
+ if file.name.endswith('.pdf'):
30
+ text = read_pdf(file)
31
+ elif file.name.endswith('.docx'):
32
+ text = read_docx(file)
33
+ else:
34
+ text = ""
35
+ resumes.append({
36
+ "filename": file.name,
37
+ "content": text
38
+ })
39
+
40
+ # SmartHire System Prompt
41
+ system_prompt = f"""
42
+ You are SmartHire, an AI Job Screening Assistant.
43
+
44
+ Your tasks:
45
+ - Analyze all candidate resumes.
46
+ - Compare against the Job Description.
47
+ - Rank candidates from best to worst fit.
48
+ - For each candidate, summarize:
49
+ - Main Strengths
50
+ - Potential Risks
51
+ - Estimated Years of Experience (guess if not explicitly stated)
52
+ - Only select candidates who meet or exceed {min_years_exp} years of experience.
53
+
54
+ Respond in a structured JSON format:
55
+ [
56
+ {{
57
+ "name": "Candidate Name (or filename)",
58
+ "strengths": ["strength1", "strength2"],
59
+ "risks": ["risk1", "risk2"],
60
+ "score": number (higher is better)
61
+ }},
62
+ ...
63
+ ]
64
+ """
65
+
66
+ # Create the user content
67
+ user_content = f"Job Description:\n{job_description}\n\nResumes:\n"
68
+ for idx, resume in enumerate(resumes):
69
+ user_content += f"\n---\nResume {idx+1} ({resume['filename']}):\n{resume['content']}\n"
70
+
71
+ # Call GPT-4 Turbo
72
+ response = openai.ChatCompletion.create(
73
+ model="gpt-4-turbo",
74
+ messages=[
75
+ {"role": "system", "content": system_prompt},
76
+ {"role": "user", "content": user_content}
77
+ ],
78
+ temperature=0.2,
79
+ max_tokens=4096
80
+ )
81
+
82
+ # Extract the output JSON
83
+ import json
84
+ try:
85
+ candidates = json.loads(response["choices"][0]["message"]["content"])
86
+ except Exception as e:
87
+ return f"⚠️ Failed to parse AI response. Error: {e}"
88
+
89
+ # Sort by score
90
+ candidates = sorted(candidates, key=lambda x: x["score"], reverse=True)
91
+
92
+ # Create Gradio Cards
93
+ cards = []
94
+ for idx, candidate in enumerate(candidates[:3]): # Only Top 3
95
+ strengths = "\n".join([f"- ✅ {s}" for s in candidate["strengths"]])
96
+ risks = "\n".join([f"- ⚠️ {r}" for r in candidate["risks"]])
97
+ card = f"""
98
+ ### {idx+1}. {candidate['name']}
99
+
100
+ **Strengths:**
101
+ {strengths}
102
+
103
+ **Risks:**
104
+ {risks}
105
+
106
+ **Fit Score:** {candidate['score']} ⭐
107
+ """
108
+ cards.append(card)
109
+
110
+ return cards
111
+
112
+ # Gradio UI
113
+ with gr.Blocks() as demo:
114
+ gr.Markdown("# 🧠 SmartHire Pro — AI Job Screening Assistant")
115
+ gr.Markdown("Upload resumes and input the Job Description to rank and analyze candidates with AI.")
116
+
117
+ with gr.Row():
118
+ resumes = gr.File(label="Upload Resumes (.pdf, .docx)", file_types=[".pdf", ".docx"], file_count="multiple")
119
+ jd = gr.Textbox(lines=8, label="Paste Job Description")
120
+ min_exp = gr.Number(label="Minimum Years of Experience (Optional)", value=0)
121
+
122
+ submit = gr.Button("Analyze Candidates")
123
+ with gr.Column():
124
+ output1 = gr.Markdown()
125
+ output2 = gr.Markdown()
126
+ output3 = gr.Markdown()
127
+
128
+ submit.click(analyze_resumes, inputs=[resumes, jd, min_exp], outputs=[output1, output2, output3])
129
+
130
+ # Launch
131
+ if __name__ == "__main__":
132
+ demo.launch()