Sumit404 commited on
Commit
851f073
·
verified ·
1 Parent(s): 11259b1

Update .app

Browse files
Files changed (1) hide show
  1. .app +20 -9
.app CHANGED
@@ -7,17 +7,28 @@ from sklearn.metrics.pairwise import cosine_similarity
7
  import gradio as gr
8
  import os
9
  import subprocess
 
 
 
 
 
10
 
11
  # Download spaCy model if not already present
12
  try:
 
13
  spacy.load("en_core_web_sm")
14
  except OSError:
 
15
  subprocess.run(["python", "-m", "spacy", "download", "en_core_web_sm"])
 
16
 
17
  class ATSValidator:
18
  def __init__(self):
 
19
  self.nlp = spacy.load("en_core_web_sm")
 
20
  self.bert_model = SentenceTransformer('all-MiniLM-L6-v2')
 
21
  self.section_weights = {
22
  'experience': 0.35,
23
  'education': 0.25,
@@ -25,7 +36,6 @@ class ATSValidator:
25
  'projects': 0.15,
26
  'certifications': 0.05
27
  }
28
- # Common technical skills
29
  self.key_skills = {
30
  'python', 'javascript', 'java', 'sql', 'aws', 'docker', 'react',
31
  'nodejs', 'machine learning', 'data analysis', 'git', 'html', 'css'
@@ -33,11 +43,13 @@ class ATSValidator:
33
 
34
  def extract_text(self, pdf_path):
35
  if not os.path.exists(pdf_path):
 
36
  return ""
37
  try:
38
  with fitz.open(pdf_path) as doc:
39
  return " ".join(page.get_text("text") for page in doc)[:100000]
40
- except:
 
41
  return ""
42
 
43
  def preprocess_text(self, text):
@@ -62,11 +74,12 @@ class ATSValidator:
62
  embeddings = self.bert_model.encode([resume_text[:1024], jd_text[:1024]])
63
  similarity = cosine_similarity([embeddings[0]], [embeddings[1]])
64
  return round(max(0, similarity.item() * 100), 2)
65
- except:
 
66
  return 0
67
 
68
  def analyze(self, resume_file, job_description):
69
- # Extract text from uploaded resume
70
  resume_text = self.extract_text(resume_file)
71
  if not resume_text:
72
  return "Error: Could not read resume file", "", "", ""
@@ -74,16 +87,13 @@ class ATSValidator:
74
  cleaned_resume = self.preprocess_text(resume_text)
75
  cleaned_jd = self.preprocess_text(job_description)
76
 
77
- # Calculate scores
78
  semantic_score = self.calculate_semantic_fit(cleaned_resume, cleaned_jd)
79
  section_scores = self.analyze_sections(resume_text)
80
  section_score = sum(self.section_weights[sec] * score * 100
81
  for sec, score in section_scores.items())
82
 
83
- # Final ATS score
84
  ats_score = np.clip(0.7 * semantic_score + 0.3 * section_score, 0, 100)
85
 
86
- # Skills analysis
87
  resume_skills = self.extract_skills(cleaned_resume)
88
  jd_skills = self.extract_skills(cleaned_jd)
89
  matched_skills = resume_skills.intersection(jd_skills)
@@ -92,7 +102,6 @@ class ATSValidator:
92
  skills_match = f"Matched Skills: {', '.join(matched_skills) if matched_skills else 'None'}\n" \
93
  f"Missing Skills: {', '.join(missing_skills) if missing_skills else 'None'}"
94
 
95
- # Improvement suggestions
96
  improvements = []
97
  if semantic_score < 60:
98
  improvements.append("Increase alignment with job description keywords and phrases")
@@ -105,13 +114,14 @@ class ATSValidator:
105
 
106
  improvement_text = "\n".join(improvements) if improvements else "Looks good!"
107
 
108
- # Score breakdown
109
  breakdown = f"Semantic Match: {semantic_score:.1f}%\nSection Score: {section_score:.1f}%"
110
 
 
111
  return f"ATS Score: {ats_score:.1f}%", skills_match, improvement_text, breakdown
112
 
113
  # Gradio Interface
114
  def process_resume(resume_file, job_description):
 
115
  validator = ATSValidator()
116
  ats_score, skills_match, improvements, breakdown = validator.analyze(resume_file.name, job_description)
117
  return ats_score, skills_match, improvements, breakdown
@@ -135,4 +145,5 @@ interface = gr.Interface(
135
 
136
  # Launch the app
137
  if __name__ == "__main__":
 
138
  interface.launch()
 
7
  import gradio as gr
8
  import os
9
  import subprocess
10
+ import logging
11
+
12
+ # Configure logging
13
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
14
+ logger = logging.getLogger(__name__)
15
 
16
  # Download spaCy model if not already present
17
  try:
18
+ logger.info("Loading spaCy model...")
19
  spacy.load("en_core_web_sm")
20
  except OSError:
21
+ logger.info("Downloading spaCy model 'en_core_web_sm'...")
22
  subprocess.run(["python", "-m", "spacy", "download", "en_core_web_sm"])
23
+ logger.info("spaCy model downloaded successfully.")
24
 
25
  class ATSValidator:
26
  def __init__(self):
27
+ logger.info("Initializing ATSValidator...")
28
  self.nlp = spacy.load("en_core_web_sm")
29
+ logger.info("spaCy model loaded.")
30
  self.bert_model = SentenceTransformer('all-MiniLM-L6-v2')
31
+ logger.info("SentenceTransformer model loaded.")
32
  self.section_weights = {
33
  'experience': 0.35,
34
  'education': 0.25,
 
36
  'projects': 0.15,
37
  'certifications': 0.05
38
  }
 
39
  self.key_skills = {
40
  'python', 'javascript', 'java', 'sql', 'aws', 'docker', 'react',
41
  'nodejs', 'machine learning', 'data analysis', 'git', 'html', 'css'
 
43
 
44
  def extract_text(self, pdf_path):
45
  if not os.path.exists(pdf_path):
46
+ logger.error(f"PDF file not found: {pdf_path}")
47
  return ""
48
  try:
49
  with fitz.open(pdf_path) as doc:
50
  return " ".join(page.get_text("text") for page in doc)[:100000]
51
+ except Exception as e:
52
+ logger.error(f"Error extracting text from PDF: {str(e)}")
53
  return ""
54
 
55
  def preprocess_text(self, text):
 
74
  embeddings = self.bert_model.encode([resume_text[:1024], jd_text[:1024]])
75
  similarity = cosine_similarity([embeddings[0]], [embeddings[1]])
76
  return round(max(0, similarity.item() * 100), 2)
77
+ except Exception as e:
78
+ logger.error(f"Error calculating semantic fit: {str(e)}")
79
  return 0
80
 
81
  def analyze(self, resume_file, job_description):
82
+ logger.info("Starting resume analysis...")
83
  resume_text = self.extract_text(resume_file)
84
  if not resume_text:
85
  return "Error: Could not read resume file", "", "", ""
 
87
  cleaned_resume = self.preprocess_text(resume_text)
88
  cleaned_jd = self.preprocess_text(job_description)
89
 
 
90
  semantic_score = self.calculate_semantic_fit(cleaned_resume, cleaned_jd)
91
  section_scores = self.analyze_sections(resume_text)
92
  section_score = sum(self.section_weights[sec] * score * 100
93
  for sec, score in section_scores.items())
94
 
 
95
  ats_score = np.clip(0.7 * semantic_score + 0.3 * section_score, 0, 100)
96
 
 
97
  resume_skills = self.extract_skills(cleaned_resume)
98
  jd_skills = self.extract_skills(cleaned_jd)
99
  matched_skills = resume_skills.intersection(jd_skills)
 
102
  skills_match = f"Matched Skills: {', '.join(matched_skills) if matched_skills else 'None'}\n" \
103
  f"Missing Skills: {', '.join(missing_skills) if missing_skills else 'None'}"
104
 
 
105
  improvements = []
106
  if semantic_score < 60:
107
  improvements.append("Increase alignment with job description keywords and phrases")
 
114
 
115
  improvement_text = "\n".join(improvements) if improvements else "Looks good!"
116
 
 
117
  breakdown = f"Semantic Match: {semantic_score:.1f}%\nSection Score: {section_score:.1f}%"
118
 
119
+ logger.info("Analysis completed successfully.")
120
  return f"ATS Score: {ats_score:.1f}%", skills_match, improvement_text, breakdown
121
 
122
  # Gradio Interface
123
  def process_resume(resume_file, job_description):
124
+ logger.info("Processing resume via Gradio interface...")
125
  validator = ATSValidator()
126
  ats_score, skills_match, improvements, breakdown = validator.analyze(resume_file.name, job_description)
127
  return ats_score, skills_match, improvements, breakdown
 
145
 
146
  # Launch the app
147
  if __name__ == "__main__":
148
+ logger.info("Launching Gradio app...")
149
  interface.launch()