Mangesh223 commited on
Commit
9f51fdd
Β·
verified Β·
1 Parent(s): 640fb7d

Updated For An ResumeAnalysis

Browse files
Files changed (1) hide show
  1. app.py +126 -6
app.py CHANGED
@@ -1,10 +1,130 @@
1
  import gradio as gr
 
 
 
 
 
2
 
3
- with gr.Blocks(fill_height=True) as demo:
4
- with gr.Sidebar():
5
- gr.Markdown("# Inference Provider")
6
- gr.Markdown("This Space showcases the mistralai/Mistral-7B-Instruct-v0.3 model, served by the together API. Sign in with your Hugging Face account to use this API.")
7
- button = gr.LoginButton("Sign in")
8
- gr.load("models/mistralai/Mistral-7B-Instruct-v0.3", accept_token=button, provider="together")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  demo.launch()
 
1
  import gradio as gr
2
+ from transformers import pipeline
3
+ import PyPDF2
4
+ import io
5
+ import re
6
+ from collections import Counter
7
 
8
+ # Initialize Mistral-7B for analysis
9
+ analyzer = pipeline("text-generation", model="mistralai/Mistral-7B-Instruct-v0.3")
10
+
11
+ # Predefined valuable skills (general mode)
12
+ GENERAL_SKILLS = {
13
+ 'communication': 2, 'problem solving': 2, 'project management': 3,
14
+ 'Python': 3, 'SQL': 2, 'Excel': 1, 'teamwork': 1
15
+ }
16
+
17
+ def extract_text_from_pdf(pdf_file):
18
+ reader = PyPDF2.PdfReader(io.BytesIO(pdf_file))
19
+ return "\n".join([page.extract_text() for page in reader.pages])
20
+
21
+ def calculate_scores(resume_text, job_desc=None):
22
+ scores = {
23
+ "Relevance to Job": 0,
24
+ "Experience Quality": 0,
25
+ "Skills Match": 0,
26
+ "Education": 0,
27
+ "Achievements": 0,
28
+ "Clarity": 10, # Start with full points, deduct for errors
29
+ "Customization": 0
30
+ }
31
+
32
+ # 1. Relevance to Job (0-20)
33
+ if job_desc:
34
+ resume_words = set(re.findall(r'\w+', resume_text.lower()))
35
+ job_words = set(re.findall(r'\w+', job_desc.lower()))
36
+ overlap = len(resume_words & job_words) / len(job_words)
37
+ scores["Relevance to Job"] = min(20, int(overlap * 20))
38
+ else:
39
+ # General employability heuristic
40
+ scores["Relevance to Job"] = min(10, sum(
41
+ 1 for skill in GENERAL_SKILLS if skill in resume_text.lower()
42
+ ))
43
+
44
+ # 2. Experience Quality (0-20)
45
+ exp_years = len(re.findall(r'\d{4}\s*[-–]\s*(?:Present|\d{4})', resume_text))
46
+ scores["Experience Quality"] = min(10, exp_years) # 1 point/year
47
+
48
+ # Quantifiable achievements
49
+ metrics = re.findall(r'(increased|reduced|saved|improved)\s+by\s+(\d+%|\$\d+)', resume_text, re.I)
50
+ scores["Experience Quality"] += min(10, len(metrics) * 2)
51
+
52
+ # 3. Skills Match (0-15)
53
+ if job_desc:
54
+ required_skills = re.findall(r'\b(?:proficient|skilled|experienced)\s+in\s+([\w\s]+)', job_desc, re.I)
55
+ found_skills = sum(1 for skill in required_skills if skill.lower() in resume_text.lower())
56
+ scores["Skills Match"] = min(15, found_skills * 3) # 3 points per skill
57
+ else:
58
+ scores["Skills Match"] = sum(
59
+ points for skill, points in GENERAL_SKILLS.items()
60
+ if skill in resume_text.lower()
61
+ )
62
+
63
+ # 4. Education (0-10)
64
+ degrees = {
65
+ 'phd': 8, 'doctorate': 8,
66
+ 'master': 6, 'msc': 6, 'mba': 6,
67
+ 'bachelor': 4, 'bs ': 4, 'ba ': 4,
68
+ 'high school': 2
69
+ }
70
+ for degree, points in degrees.items():
71
+ if degree in resume_text.lower():
72
+ scores["Education"] = max(scores["Education"], points)
73
+
74
+ # 5. Achievements (0-15)
75
+ quantifiers = re.findall(r'(?:achieved|reached|attained)\s+\d+%|\$\d+', resume_text, re.I)
76
+ scores["Achievements"] = min(15, len(quantifiers) * 3)
77
+
78
+ # 6. Clarity (0-10)
79
+ # Deduct for errors
80
+ typos = len(re.findall(r'\b(?:responsibilities|accomplishment|experiance)\b', resume_text, re.I))
81
+ scores["Clarity"] -= min(8, typos)
82
 
83
+ # 7. Customization (0-10)
84
+ if job_desc and 'summary' in resume_text.lower():
85
+ job_title = re.search(r'\b(?:senior|junior)?\s*\w+\s*(?:developer|engineer|manager)', job_desc, re.I)
86
+ if job_title and job_title.group().lower() in resume_text.lower():
87
+ scores["Customization"] += 5
88
+
89
+ total = sum(scores.values())
90
+ return scores, min(100, total) # Cap at 100
91
+
92
+ def analyze_resume(pdf_file, job_desc=None):
93
+ resume_text = extract_text_from_pdf(pdf_file)
94
+ scores, total = calculate_scores(resume_text, job_desc)
95
+
96
+ # Generate AI feedback
97
+ prompt = f"""
98
+ Given these resume scores: {scores}
99
+ Provide concise feedback in this format:
100
+
101
+ πŸ” Overall Score: {total}/100
102
+ βœ… Strengths: [Top 2 scoring categories]
103
+ πŸ“Œ Improvements: [2 weakest categories with specific advice]
104
+ """
105
+ analysis = analyzer(prompt, max_new_tokens=300)[0]["generated_text"]
106
+
107
+ # Format results
108
+ breakdown = "\n".join([f"{k}: {v}/{(20 if k=='Experience Quality' else 15 if k=='Skills Match' else 10)}"
109
+ for k, v in scores.items()])
110
+
111
+ return f"{analysis}\n\nπŸ“Š Detailed Breakdown:\n{breakdown}"
112
+
113
+ # Gradio Interface
114
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
115
+ gr.Markdown("# 🎯 Smart Resume Analyzer")
116
+ with gr.Row():
117
+ with gr.Column():
118
+ resume = gr.File(label="Upload Resume (PDF)")
119
+ job_desc = gr.Textbox(label="Optional: Paste Job Description", lines=3)
120
+ analyze_btn = gr.Button("Analyze", variant="primary")
121
+ with gr.Column():
122
+ output = gr.Textbox(label="Analysis Results", interactive=False)
123
+
124
+ analyze_btn.click(
125
+ fn=analyze_resume,
126
+ inputs=[resume, job_desc],
127
+ outputs=output
128
+ )
129
+
130
  demo.launch()