import streamlit as st
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import re
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
import string
import json
import os
from utils import load_job_data, preprocess_text, get_top_skills, get_job_recommendations
# Download NLTK resources
try:
nltk.download('punkt')
nltk.download('stopwords')
except:
pass # In case downloads fail, continue with what's available
# Page configuration
st.set_page_config(
page_title="Job Title Recommender",
page_icon="💼",
layout="wide"
)
# Custom CSS
st.markdown("""
""", unsafe_allow_html=True)
# Initialize session state
if 'job_data' not in st.session_state:
st.session_state.job_data = load_job_data()
if 'vectorizer' not in st.session_state:
st.session_state.vectorizer = None
if 'job_vectors' not in st.session_state:
st.session_state.job_vectors = None
# Header
st.markdown('
💼 Job Title Recommender
', unsafe_allow_html=True)
st.markdown('', unsafe_allow_html=True)
# Built with anycoder
st.markdown('', unsafe_allow_html=True)
# Main content
col1, col2 = st.columns([1, 1])
with col1:
st.header("📝 Input Your Profile")
# Input method selection
input_method = st.radio(
"Choose input method:",
["Text Input", "File Upload"],
horizontal=True
)
if input_method == "Text Input":
profile_text = st.text_area(
"Paste your LinkedIn profile or resume text here:",
height=300,
placeholder="Include your work experience, skills, education, and any other relevant information..."
)
else:
uploaded_file = st.file_uploader(
"Upload your resume (PDF or TXT):",
type=["pdf", "txt"],
help="Upload your resume file to analyze"
)
if uploaded_file:
try:
if uploaded_file.type == "application/pdf":
# For PDF files (would need additional libraries)
st.warning("PDF parsing requires additional libraries. Please use text input or upload a .txt file.")
profile_text = ""
else:
# For text files
profile_text = uploaded_file.read().decode("utf-8")
st.success("File uploaded successfully!")
except Exception as e:
st.error(f"Error reading file: {e}")
profile_text = ""
# Skills input
st.subheader("Key Skills")
skills_input = st.text_input(
"Enter your key skills (comma separated):",
placeholder="e.g., Python, Machine Learning, Project Management"
)
# Experience level
experience_level = st.select_slider(
"Years of Experience:",
options=["0-2 years", "3-5 years", "6-10 years", "10+ years"],
value="3-5 years"
)
# Education level
education_level = st.selectbox(
"Highest Education Level:",
["High School", "Associate Degree", "Bachelor's Degree", "Master's Degree", "PhD"]
)
# Analyze button
analyze_button = st.button("🔍 Analyze & Get Recommendations", type="primary")
with col2:
st.header("🎯 Your Recommendations")
if analyze_button and profile_text:
with st.spinner("Analyzing your profile..."):
try:
# Preprocess the input text
processed_text = preprocess_text(profile_text)
# Extract skills from input
input_skills = [skill.strip() for skill in skills_input.split(",")] if skills_input else []
extracted_skills = get_top_skills(processed_text, top_n=10)
# Combine all skills
all_skills = list(set(input_skills + extracted_skills))
# Create user profile vector
if st.session_state.vectorizer is None or st.session_state.job_vectors is None:
# Initialize vectorizer and job vectors if not already done
job_descriptions = st.session_state.job_data['description'].tolist()
st.session_state.vectorizer = TfidfVectorizer(stop_words='english', max_features=5000)
st.session_state.job_vectors = st.session_state.vectorizer.fit_transform(job_descriptions)
# Transform user profile
user_vector = st.session_state.vectorizer.transform([processed_text])
# Get recommendations
recommendations = get_job_recommendations(
user_vector,
st.session_state.job_vectors,
st.session_state.job_data,
all_skills,
experience_level,
education_level,
top_n=5
)
if recommendations.empty:
st.warning("No suitable job titles found. Try adding more details to your profile.")
else:
st.success(f"Found {len(recommendations)} suitable job titles for you!")
for idx, row in recommendations.iterrows():
with st.expander(f"🏆 {row['job_title']} (Match: {row['match_score']:.1%})"):
st.markdown(f"**Industry:** {row['industry']}")
st.markdown(f"**Experience Level:** {row['experience_level']}")
st.markdown(f"**Education Requirement:** {row['education_requirement']}")
# Display skills
st.markdown("**Key Skills:**")
job_skills = [skill.strip() for skill in row['required_skills'].split(",")]
for skill in job_skills[:5]: # Show top 5 skills
st.markdown(f'{skill}', unsafe_allow_html=True)
st.markdown(f"**Average Salary:** {row['avg_salary']}")
if st.button(f"Learn more about {row['job_title']}", key=f"learn_{idx}"):
st.info(f"This would typically link to more information about the {row['job_title']} role.")
# Show skills analysis
st.subheader("Your Skills Analysis")
if all_skills:
st.markdown("**Detected Skills:**")
for skill in all_skills[:10]: # Show top 10 skills
st.markdown(f'{skill}', unsafe_allow_html=True)
else:
st.info("No specific skills detected. Consider adding more details to your profile.")
except Exception as e:
st.error(f"An error occurred during analysis: {e}")
elif analyze_button and not profile_text:
st.warning("Please enter your profile information or upload a file.")
else:
st.info("Enter your LinkedIn profile or resume information and click 'Analyze' to get job recommendations.")
# Footer
st.markdown("""
""", unsafe_allow_html=True)