Job_Catalyst-AI / app.py
shreyan67's picture
Update app.py
7ad3944 verified
raw
history blame
5 kB
import streamlit as st
import fitz # PyMuPDF for PDF extraction
import pandas as pd
import torch
from sentence_transformers import SentenceTransformer
from model import JobRecommendationSystem
# ----------------- PAGE CONFIG (must be FIRST) -----------------
st.set_page_config(page_title="AI Job Recommender", page_icon="πŸ’Ό", layout="wide")
# ----------------- CACHE HEAVY STUFF -----------------
@st.cache_resource
def load_model():
"""Load and quantize the SentenceTransformer model once"""
try:
model = SentenceTransformer("./paraphrase-MiniLM-L6-v2", device="cpu") # local
except Exception:
model = SentenceTransformer("sentence-transformers/paraphrase-MiniLM-L6-v2", device="cpu") # fallback
return torch.quantization.quantize_dynamic(model, {torch.nn.Linear}, dtype=torch.qint8)
@st.cache_resource
def load_recommender():
"""Load recommender system once with cached embeddings"""
return JobRecommendationSystem("JobsFE.csv")
MODEL = load_model()
recommender = load_recommender()
# ----------------- STREAMLIT UI -----------------
st.markdown(
"""
<style>
.recommend-card {
padding: 20px;
border-radius: 15px;
background-color: #f9f9f9;
margin-bottom: 20px;
box-shadow: 0 4px 8px rgba(0,0,0,0.05);
}
.job-title {
font-size: 20px;
font-weight: 700;
color: #2c3e50;
}
.company-name {
font-size: 16px;
font-weight: 500;
color: #16a085;
}
.salary {
font-size: 15px;
font-weight: 500;
color: #e67e22;
}
</style>
""",
unsafe_allow_html=True
)
st.title("πŸ’Ό AI-Powered Job Recommendation System")
st.write("πŸ“„ Upload your resume as a **PDF file** and get tailored job recommendations with direct apply links.")
# ----------------- FILE UPLOADER -----------------
uploaded_file = st.file_uploader("Upload your resume (PDF only)", type=["pdf"], help="Only PDF resumes are supported.")
def extract_text_from_pdf(pdf_file):
"""Extract text from uploaded PDF resume"""
doc = fitz.open(stream=pdf_file.read(), filetype="pdf")
text = "\n".join([page.get_text("text") for page in doc])
return text.strip()
resume_text = ""
if uploaded_file:
with st.spinner("⏳ Extracting text from your resume..."):
resume_text = extract_text_from_pdf(uploaded_file)
# ----------------- JOB RECOMMENDATIONS -----------------
if st.button("πŸ” Recommend Jobs"):
if resume_text:
with st.spinner("πŸ€– Analyzing your resume and finding best matches..."):
job_results = recommender.recommend_jobs(resume_text, top_n=20)
st.success(f"βœ… Found {len(job_results)} job recommendations for you!")
for i, job in enumerate(job_results, start=1):
with st.container():
st.markdown('<div class="recommend-card">', unsafe_allow_html=True)
st.markdown(f"<div class='job-title'> {i}. {job.get('position', 'N/A')} </div>", unsafe_allow_html=True)
st.markdown(
f"<div class='company-name'>🏒 {job.get('workplace', 'N/A')} ({job.get('formatted_work_type', 'N/A')})</div>",
unsafe_allow_html=True,
)
if job.get("salary_range") and "N/A" not in job.get("salary_range"):
st.markdown(f"<div class='salary'>πŸ’° {job['salary_range']}</div>", unsafe_allow_html=True)
if job.get("experience_level") and job.get("experience_level") != "N/A":
st.write(f"**🎯 Experience Level:** {job['experience_level']}")
if job.get("job_role_and_duties"):
st.write(f"**πŸ“ Duties:** {job['job_role_and_duties']}")
if job.get("skills"):
st.write(f"**πŸ›  Required Skills:** {job['skills']}")
if job.get("benefits"):
st.write(f"**🎁 Benefits:** {job['benefits']}")
if job.get("location") and job.get("location").strip(", "):
st.write(f"**πŸ“ Location:** {job['location']}")
if job.get("company_size") and job.get("company_size") != "N/A":
st.write(f"**🏒 Company Size:** {job['company_size']}")
if job.get("employee_count") and job.get("employee_count") != "N/A":
st.write(f"**πŸ‘₯ Employees:** {job['employee_count']}")
if job.get("company_website") and job.get("company_website") != "N/A":
st.markdown(f"[🌐 Company Website]({job['company_website']})", unsafe_allow_html=True)
if job.get("apply_link") and job.get("apply_link") != "N/A":
st.markdown(f"[πŸ‘‰ Apply Here]({job['apply_link']})", unsafe_allow_html=True)
st.markdown('</div>', unsafe_allow_html=True)
else:
st.warning("⚠️ Please upload a valid PDF resume before proceeding.")