Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -87,7 +87,7 @@ Important:
|
|
| 87 |
Resume: {resume}
|
| 88 |
Job Description: {jd}
|
| 89 |
[/INST]""".format(
|
| 90 |
-
resume=resume_text[:3000],
|
| 91 |
jd=job_description[:1000]
|
| 92 |
)
|
| 93 |
|
|
@@ -99,37 +99,41 @@ Job Description: {jd}
|
|
| 99 |
"inputs": prompt,
|
| 100 |
"parameters": {
|
| 101 |
"max_new_tokens": 800,
|
| 102 |
-
"temperature": 0.3,
|
| 103 |
-
"do_sample": False
|
| 104 |
}
|
| 105 |
},
|
| 106 |
-
timeout=45
|
| 107 |
)
|
| 108 |
|
| 109 |
# Handle API errors
|
| 110 |
if response.status_code != 200:
|
| 111 |
error_msg = response.json().get("error", "Unknown API error")
|
| 112 |
-
return {
|
|
|
|
|
|
|
|
|
|
| 113 |
|
| 114 |
# Process response
|
| 115 |
raw_output = response.json()[0]['generated_text']
|
|
|
|
|
|
|
| 116 |
result = extract_json_from_text(raw_output)
|
| 117 |
|
| 118 |
-
if
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
|
|
|
|
|
|
|
|
|
| 123 |
|
| 124 |
-
#
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
"partial_response": result
|
| 130 |
-
}
|
| 131 |
-
|
| 132 |
-
return result
|
| 133 |
|
| 134 |
except requests.exceptions.RequestException as e:
|
| 135 |
return {"error": f"Network error: {str(e)}"}
|
|
@@ -138,8 +142,7 @@ Job Description: {jd}
|
|
| 138 |
|
| 139 |
# Enhanced Gradio Interface
|
| 140 |
with gr.Blocks(title="ATS Resume Analyzer", theme=gr.themes.Soft()) as demo:
|
| 141 |
-
gr.Markdown("""# ATS Resume Analyzer
|
| 142 |
-
Upload your resume and job description to get ATS compatibility analysis""")
|
| 143 |
|
| 144 |
with gr.Row():
|
| 145 |
with gr.Column():
|
|
@@ -158,47 +161,59 @@ with gr.Blocks(title="ATS Resume Analyzer", theme=gr.themes.Soft()) as demo:
|
|
| 158 |
with gr.Column():
|
| 159 |
output_tabs = gr.Tabs()
|
| 160 |
with output_tabs:
|
| 161 |
-
with gr.Tab("
|
| 162 |
-
json_output = gr.JSON(label="
|
| 163 |
-
|
| 164 |
-
|
|
|
|
|
|
|
|
|
|
| 165 |
status = gr.Textbox(label="Status", interactive=False)
|
| 166 |
|
| 167 |
def display_results(file, job_description):
|
| 168 |
"""Handle results display with proper error handling"""
|
| 169 |
result = analyze_with_huggingface(file, job_description)
|
| 170 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
if "error" in result:
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 177 |
|
| 178 |
-
return
|
| 179 |
-
json_output: result,
|
| 180 |
-
raw_output: json.dumps(result, indent=2),
|
| 181 |
-
status: "Analysis complete!"
|
| 182 |
-
}
|
| 183 |
|
| 184 |
analyze_btn.click(
|
| 185 |
fn=display_results,
|
| 186 |
inputs=[file_input, jd_input],
|
| 187 |
-
outputs=[json_output, raw_output, status]
|
| 188 |
)
|
| 189 |
|
| 190 |
-
# ... (all your existing code remains the same until the launch part) ...
|
| 191 |
-
|
| 192 |
if __name__ == "__main__":
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
# Option 1: Simple queue
|
| 196 |
-
demo.queue()
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
# Then launch
|
| 201 |
-
demo.launch(
|
| 202 |
allowed_paths=["*"],
|
| 203 |
-
|
| 204 |
)
|
|
|
|
| 87 |
Resume: {resume}
|
| 88 |
Job Description: {jd}
|
| 89 |
[/INST]""".format(
|
| 90 |
+
resume=resume_text[:3000],
|
| 91 |
jd=job_description[:1000]
|
| 92 |
)
|
| 93 |
|
|
|
|
| 99 |
"inputs": prompt,
|
| 100 |
"parameters": {
|
| 101 |
"max_new_tokens": 800,
|
| 102 |
+
"temperature": 0.3,
|
| 103 |
+
"do_sample": False
|
| 104 |
}
|
| 105 |
},
|
| 106 |
+
timeout=45
|
| 107 |
)
|
| 108 |
|
| 109 |
# Handle API errors
|
| 110 |
if response.status_code != 200:
|
| 111 |
error_msg = response.json().get("error", "Unknown API error")
|
| 112 |
+
return {
|
| 113 |
+
"error": f"API request failed: {error_msg}",
|
| 114 |
+
"api_response": response.text
|
| 115 |
+
}
|
| 116 |
|
| 117 |
# Process response
|
| 118 |
raw_output = response.json()[0]['generated_text']
|
| 119 |
+
|
| 120 |
+
# Try to extract JSON
|
| 121 |
result = extract_json_from_text(raw_output)
|
| 122 |
|
| 123 |
+
if result:
|
| 124 |
+
# Validate JSON structure
|
| 125 |
+
required_keys = {"analysis", "overall_score"}
|
| 126 |
+
if all(key in result for key in required_keys):
|
| 127 |
+
return {
|
| 128 |
+
"structured_result": result,
|
| 129 |
+
"raw_response": raw_output
|
| 130 |
+
}
|
| 131 |
|
| 132 |
+
# If JSON extraction failed, return raw output
|
| 133 |
+
return {
|
| 134 |
+
"raw_response": raw_output,
|
| 135 |
+
"error": "Could not extract valid JSON"
|
| 136 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
|
| 138 |
except requests.exceptions.RequestException as e:
|
| 139 |
return {"error": f"Network error: {str(e)}"}
|
|
|
|
| 142 |
|
| 143 |
# Enhanced Gradio Interface
|
| 144 |
with gr.Blocks(title="ATS Resume Analyzer", theme=gr.themes.Soft()) as demo:
|
| 145 |
+
gr.Markdown("""# ATS Resume Analyzer""")
|
|
|
|
| 146 |
|
| 147 |
with gr.Row():
|
| 148 |
with gr.Column():
|
|
|
|
| 161 |
with gr.Column():
|
| 162 |
output_tabs = gr.Tabs()
|
| 163 |
with output_tabs:
|
| 164 |
+
with gr.Tab("Analysis Results"):
|
| 165 |
+
json_output = gr.JSON(label="Structured Analysis")
|
| 166 |
+
summary_output = gr.Textbox(label="Summary", interactive=False)
|
| 167 |
+
with gr.Tab("API Response"):
|
| 168 |
+
raw_output = gr.Textbox(label="Raw API Response", lines=10)
|
| 169 |
+
with gr.Tab("Debug Info"):
|
| 170 |
+
status_output = gr.Textbox(label="Status Info", lines=5)
|
| 171 |
status = gr.Textbox(label="Status", interactive=False)
|
| 172 |
|
| 173 |
def display_results(file, job_description):
|
| 174 |
"""Handle results display with proper error handling"""
|
| 175 |
result = analyze_with_huggingface(file, job_description)
|
| 176 |
|
| 177 |
+
output = {
|
| 178 |
+
json_output: None,
|
| 179 |
+
summary_output: None,
|
| 180 |
+
raw_output: None,
|
| 181 |
+
status_output: None,
|
| 182 |
+
status: ""
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
if "error" in result:
|
| 186 |
+
output.update({
|
| 187 |
+
status: f"Error: {result['error']}",
|
| 188 |
+
status_output: str(result),
|
| 189 |
+
raw_output: result.get("api_response") or result.get("raw_response") or ""
|
| 190 |
+
})
|
| 191 |
+
elif "structured_result" in result:
|
| 192 |
+
structured = result["structured_result"]
|
| 193 |
+
output.update({
|
| 194 |
+
json_output: structured["analysis"],
|
| 195 |
+
summary_output: structured.get("summary", ""),
|
| 196 |
+
raw_output: result["raw_response"],
|
| 197 |
+
status: "Analysis complete!",
|
| 198 |
+
status_output: "Successfully parsed JSON response"
|
| 199 |
+
})
|
| 200 |
+
else:
|
| 201 |
+
output.update({
|
| 202 |
+
raw_output: result.get("raw_response", "No response received"),
|
| 203 |
+
status: "Received non-JSON response",
|
| 204 |
+
status_output: "The API returned a response but it couldn't be parsed as JSON"
|
| 205 |
+
})
|
| 206 |
|
| 207 |
+
return output
|
|
|
|
|
|
|
|
|
|
|
|
|
| 208 |
|
| 209 |
analyze_btn.click(
|
| 210 |
fn=display_results,
|
| 211 |
inputs=[file_input, jd_input],
|
| 212 |
+
outputs=[json_output, summary_output, raw_output, status_output, status]
|
| 213 |
)
|
| 214 |
|
|
|
|
|
|
|
| 215 |
if __name__ == "__main__":
|
| 216 |
+
demo.queue().launch(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
allowed_paths=["*"],
|
| 218 |
+
|
| 219 |
)
|