Mangesh223 commited on
Commit
5a8b43e
·
verified ·
1 Parent(s): 37d7e9d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -28
app.py CHANGED
@@ -5,7 +5,7 @@ import docx
5
  import requests
6
  import json
7
 
8
- # Function to extract text from PDF (unchanged)
9
  def extract_text_from_pdf(file):
10
  pdf_reader = PyPDF2.PdfReader(file)
11
  text = ""
@@ -13,13 +13,13 @@ def extract_text_from_pdf(file):
13
  text += page.extract_text()
14
  return text
15
 
16
- # Function to extract text from Word document (unchanged)
17
  def extract_text_from_docx(file):
18
  doc = docx.Document(file)
19
  text = "\n".join([para.text for para in doc.paragraphs])
20
  return text
21
 
22
- # Function to process uploaded file (only added case-insensitive check)
23
  def process_uploaded_file(file):
24
  filename = file.name.lower() # Case-insensitive check
25
  if filename.endswith(".pdf"):
@@ -29,16 +29,15 @@ def process_uploaded_file(file):
29
  else:
30
  raise ValueError("Unsupported file format. Please upload a PDF or Word document.")
31
 
32
- # Function to call Together API (unchanged except for timeout)
33
  def analyze_with_mistral(resume_text, job_description):
34
  TOGETHER_API_KEY = os.getenv("HUGGINGFACE_API_KEY")
35
  url = "https://api.together.xyz/v1/chat/completions"
36
 
37
-
38
  messages = [
39
- {
40
- "role": "system",
41
- "content": """You are an expert in Applicant Tracking Systems (ATS) and resume optimization.
42
  Your task is to analyze resumes against job descriptions to provide detailed, actionable feedback
43
  that helps candidates pass ATS screening and impress human reviewers.
44
 
@@ -52,10 +51,10 @@ Follow these guidelines when analyzing resumes:
52
  7. Be thorough but concise in your analysis
53
 
54
  Your analysis must be comprehensive yet practical for the candidate to implement."""
55
- },
56
- {
57
- "role": "user",
58
- "content": f"""
59
  Analyze the following resume against the job description for ATS compatibility and hiring potential.
60
 
61
  RESUME:
@@ -113,8 +112,8 @@ Provide a detailed analysis in EXACTLY the following JSON format:
113
 
114
  Ensure all recommendations are specific, actionable, and tailored to both the resume content and job description.
115
  """
116
- }
117
- ]
118
 
119
  payload = {
120
  "model": "mistralai/Mistral-7B-Instruct-v0.3",
@@ -136,30 +135,40 @@ Ensure all recommendations are specific, actionable, and tailored to both the re
136
  result = response.json()
137
  content = result.get("choices", [{}])[0].get("message", {}).get("content", "{}")
138
 
139
- # Parse and validate the JSON structure
140
- parsed = json.loads(content)
141
- if "ATS Parameters" not in parsed or "Score" not in parsed:
142
- raise ValueError("API returned invalid format")
143
- return parsed
 
 
 
 
 
144
 
145
- except Exception as e:
146
  return {"error": f"API request failed: {str(e)}"}
 
 
147
 
148
- # Main function (only added JSON validation)
149
  def analyze_resume(file, job_description):
150
  try:
 
 
 
 
 
151
  resume_text = process_uploaded_file(file)
152
  result = analyze_with_mistral(resume_text, job_description)
153
 
154
- # Ensure the output matches your original format
155
- if isinstance(result, dict) and "error" in result:
156
- return json.dumps(result, indent=2)
157
- return result
158
 
159
  except Exception as e:
160
- return json.dumps({"error": str(e)}, indent=2)
161
 
162
- # Gradio interface (only changed file component type)
163
  with gr.Blocks(fill_height=True, title="Smart ATS Resume Analyzer") as demo:
164
  with gr.Sidebar():
165
  gr.Markdown("# Smart ATS Resume Analyzer")
@@ -170,7 +179,7 @@ with gr.Blocks(fill_height=True, title="Smart ATS Resume Analyzer") as demo:
170
  resume_upload = gr.File(
171
  label="Upload Resume (PDF or Word)",
172
  file_types=[".pdf", ".docx"],
173
- type="filepath" # Only this line changed
174
  )
175
  job_desc = gr.Textbox(label="Job Description", lines=10, placeholder="Paste the job description here...")
176
  submit_btn = gr.Button("Analyze Resume")
 
5
  import requests
6
  import json
7
 
8
+ # Function to extract text from PDF
9
  def extract_text_from_pdf(file):
10
  pdf_reader = PyPDF2.PdfReader(file)
11
  text = ""
 
13
  text += page.extract_text()
14
  return text
15
 
16
+ # Function to extract text from Word document
17
  def extract_text_from_docx(file):
18
  doc = docx.Document(file)
19
  text = "\n".join([para.text for para in doc.paragraphs])
20
  return text
21
 
22
+ # Function to process uploaded file
23
  def process_uploaded_file(file):
24
  filename = file.name.lower() # Case-insensitive check
25
  if filename.endswith(".pdf"):
 
29
  else:
30
  raise ValueError("Unsupported file format. Please upload a PDF or Word document.")
31
 
32
+ # Function to call Together API
33
  def analyze_with_mistral(resume_text, job_description):
34
  TOGETHER_API_KEY = os.getenv("HUGGINGFACE_API_KEY")
35
  url = "https://api.together.xyz/v1/chat/completions"
36
 
 
37
  messages = [
38
+ {
39
+ "role": "system",
40
+ "content": """You are an expert in Applicant Tracking Systems (ATS) and resume optimization.
41
  Your task is to analyze resumes against job descriptions to provide detailed, actionable feedback
42
  that helps candidates pass ATS screening and impress human reviewers.
43
 
 
51
  7. Be thorough but concise in your analysis
52
 
53
  Your analysis must be comprehensive yet practical for the candidate to implement."""
54
+ },
55
+ {
56
+ "role": "user",
57
+ "content": f"""
58
  Analyze the following resume against the job description for ATS compatibility and hiring potential.
59
 
60
  RESUME:
 
112
 
113
  Ensure all recommendations are specific, actionable, and tailored to both the resume content and job description.
114
  """
115
+ }
116
+ ]
117
 
118
  payload = {
119
  "model": "mistralai/Mistral-7B-Instruct-v0.3",
 
135
  result = response.json()
136
  content = result.get("choices", [{}])[0].get("message", {}).get("content", "{}")
137
 
138
+ # The key fix: Safely parse the JSON content
139
+ try:
140
+ parsed = json.loads(content)
141
+ # Check if the JSON structure is valid for our use case
142
+ # Note: We've updated this validation to match our new JSON structure
143
+ if "ATS_Compatibility" not in parsed or "Overall_Assessment" not in parsed:
144
+ return {"error": "API returned unexpected JSON structure"}
145
+ return parsed
146
+ except json.JSONDecodeError as e:
147
+ return {"error": f"Failed to parse API response: {str(e)}", "raw_content": content[:500] + "..." if len(content) > 500 else content}
148
 
149
+ except requests.exceptions.RequestException as e:
150
  return {"error": f"API request failed: {str(e)}"}
151
+ except Exception as e:
152
+ return {"error": f"Unexpected error: {str(e)}"}
153
 
154
+ # Main function
155
  def analyze_resume(file, job_description):
156
  try:
157
+ if not file:
158
+ return json.dumps({"error": "Please upload a resume file"}, indent=2)
159
+ if not job_description:
160
+ return json.dumps({"error": "Please enter a job description"}, indent=2)
161
+
162
  resume_text = process_uploaded_file(file)
163
  result = analyze_with_mistral(resume_text, job_description)
164
 
165
+ # Return as formatted JSON string for better display
166
+ return json.dumps(result, indent=2)
 
 
167
 
168
  except Exception as e:
169
+ return json.dumps({"error": f"Error analyzing resume: {str(e)}"}, indent=2)
170
 
171
+ # Gradio interface
172
  with gr.Blocks(fill_height=True, title="Smart ATS Resume Analyzer") as demo:
173
  with gr.Sidebar():
174
  gr.Markdown("# Smart ATS Resume Analyzer")
 
179
  resume_upload = gr.File(
180
  label="Upload Resume (PDF or Word)",
181
  file_types=[".pdf", ".docx"],
182
+ type="filepath"
183
  )
184
  job_desc = gr.Textbox(label="Job Description", lines=10, placeholder="Paste the job description here...")
185
  submit_btn = gr.Button("Analyze Resume")