LovnishVerma's picture
Update app.py
f747c18 verified
import streamlit as st
import requests
import json
import os
# CONFIG
# For Hugging Face Spaces (Same container)
BACKEND_URL = "http://127.0.0.1:8000/analyze"
st.set_page_config(page_title="Smart ATS", page_icon="🎯", layout="wide")
# CUSTOM CSS
st.markdown("""
<style>
.metric-card {
background-color: #f0f2f6;
padding: 20px;
border-radius: 10px;
border-left: 5px solid #4CAF50;
}
.skill-tag {
display: inline-block;
padding: 5px 10px;
margin: 2px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
}
.match { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
.missing { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
</style>
""", unsafe_allow_html=True)
st.title("🎯 AI Smart Resume Screen")
st.markdown("Compare resumes against job descriptions to find the perfect fit.")
# LAYOUT: Two columns for input
col1, col2 = st.columns([1, 1])
with col1:
st.subheader("1. Job Description (Optional)")
jd_input = st.text_area("Paste the Job Description here...", height=200,
placeholder="e.g. Seeking a Senior Python Developer with AWS experience...")
with col2:
st.subheader("2. Candidate Resume")
uploaded_file = st.file_uploader("Upload PDF", type="pdf")
# ACTION
if st.button("Analyze Fit", type="primary"):
if not uploaded_file:
st.warning("Please upload a resume first.")
else:
with st.spinner("Analyzing candidate against requirements..."):
try:
# Prepare Payload
files = {"file": (uploaded_file.name, uploaded_file.getvalue(), "application/pdf")}
data = {"job_description": jd_input} if jd_input else {}
response = requests.post(BACKEND_URL, files=files, data=data, timeout=60)
if response.status_code == 200:
result = response.json()
if "error" in result:
st.error(result["error"])
else:
# --- DASHBOARD UI ---
candidate = result.get("candidate", {})
analysis = result.get("match_analysis", {})
# 1. Header (Candidate Info)
st.divider()
c1, c2, c3, c4 = st.columns(4)
c1.markdown(f"**Name:** {candidate.get('name', 'N/A')}")
c2.markdown(f"**Email:** {candidate.get('email', 'N/A')}")
c3.markdown(f"**Phone:** {candidate.get('phone', 'N/A')}")
# 2. Score Section (Only if JD provided)
if jd_input:
score = analysis.get("score", 0)
verdict = analysis.get("verdict", "N/A")
# Color coding the score
score_color = "green" if score >= 80 else "orange" if score >= 50 else "red"
st.markdown(f"""
<div class="metric-card">
<h3 style="margin:0">Match Score: <span style="color:{score_color}">{score}%</span></h3>
<p style="margin:0"><strong>Verdict:</strong> {verdict}</p>
<p style="margin-top:10px"><em>"{analysis.get('reasoning', '')}"</em></p>
</div>
""", unsafe_allow_html=True)
st.markdown("### 🧩 Skill Gap Analysis")
k1, k2 = st.columns(2)
with k1:
st.success("βœ… Matching Skills")
matches = analysis.get("matching_skills", [])
if matches:
html = "".join([f'<span class="skill-tag match">{s}</span>' for s in matches])
st.markdown(html, unsafe_allow_html=True)
else:
st.write("No direct skill matches found.")
with k2:
st.error("⚠️ Missing / To Improve")
missing = analysis.get("missing_skills", [])
if missing:
html = "".join([f'<span class="skill-tag missing">{s}</span>' for s in missing])
st.markdown(html, unsafe_allow_html=True)
else:
st.write("No major skills missing!")
else:
# Standard Extraction View (No JD)
st.info("πŸ’‘ Paste a Job Description on the left to see a Match Score!")
st.markdown("### πŸ›  Skills Detected")
st.write(", ".join(candidate.get("skills", [])))
with st.expander("View Raw JSON Data"):
st.json(result)
else:
st.error(f"Server Error: {response.text}")
except Exception as e:
st.error(f"Connection Error: {e}")