Spaces:
Sleeping
Sleeping
File size: 4,973 Bytes
7b7951a a8d427d 7b7951a 50c4eb9 7b7951a 50c4eb9 7b7951a 50c4eb9 7b7951a cef88ad 7b7951a 50c4eb9 a25c8cf 7b7951a 50c4eb9 7b7951a 50c4eb9 7b7951a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | import streamlit as st
import os
import io
import pdfplumber
import pandas as pd
from dotenv import load_dotenv
from groq import Groq
import gspread
from oauth2client.service_account import ServiceAccountCredentials
from docx import Document
# Page config
st.set_page_config(page_title="π AI ResumeSync Analyzer", layout="centered")
# Load env vars
load_dotenv()
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
if not GROQ_API_KEY:
st.error("β GROQ API Key is missing. Please add it in the .env file or Hugging Face Secrets.")
st.stop()
# Load Google Sheet
df = pd.DataFrame()
sheet_loaded = False
scope = ["https://spreadsheets.google.com/feeds", "https://www.googleapis.com/auth/drive"]
if os.path.exists("credentials.json"):
try:
creds = ServiceAccountCredentials.from_json_keyfile_name("credentials.json", scope)
client = gspread.authorize(creds)
sheet = client.open("Job_Listings").sheet1
data = sheet.get_all_records()
df = pd.DataFrame(data)
sheet_loaded = True
except Exception as e:
st.warning(f"β οΈ Could not load job listings from Google Sheet: {e}")
# Fallback job listing
if not sheet_loaded:
df = pd.DataFrame([{
"Title": "Software Engineer",
"Skills": "Python, Django, SQL",
"Experience": "2+ years",
"Education": "BS in Computer Science"
}])
# Groq client
groq_client = Groq(api_key=GROQ_API_KEY)
# UI: Title
st.title("π AI ResumeSync Analyzer")
st.markdown("Upload your resume below to receive tailored job match analysis, skill suggestions, and a personalized cover letter.")
# File uploader
uploaded_file = st.file_uploader("π€ Upload your resume (PDF, DOCX, or TXT)", type=["pdf", "docx", "txt"])
# Resume text extractor
def extract_resume_text(uploaded_file):
try:
filename = uploaded_file.name.lower()
buffer = io.BytesIO(uploaded_file.getvalue()) # Use getvalue() instead of read()
buffer.seek(0)
if filename.endswith(".pdf"):
text = ""
with pdfplumber.open(buffer) as pdf:
for page in pdf.pages:
page_text = page.extract_text()
if page_text:
text += page_text + "\n"
return text.strip()
elif filename.endswith(".docx"):
doc = Document(buffer)
return "\n".join(para.text for para in doc.paragraphs if para.text.strip())
elif filename.endswith(".txt"):
return buffer.getvalue().decode("utf-8", errors="ignore")
else:
return None
except Exception as e:
st.error(f"β Error reading resume file: {e}")
return None
# Main logic
if uploaded_file:
with st.spinner("π Analyzing your resume..."):
resume_text = extract_resume_text(uploaded_file)
if not resume_text or resume_text.strip() == "":
st.error("β No readable content in the uploaded resume.")
st.stop()
# AI Prompt
prompt = f"""
You are an expert AI Resume Analyzer. Based on the resume and job listings provided, return a detailed, formatted response covering:
1. β
Match Score (as percentage)
2. π― Recommended Jobs (top 3 that match well)
3. π Qualification Ranking (1 to 10)
4. π§© Skill Gaps & Suggestions
5. π οΈ Keyword Optimization Suggestions
6. π Education & Experience Alignment
7. π° Estimated Salary Range
8. π Job Market Trends (optional)
9. βοΈ Personalized Cover Letter
Return the output with clear headings and markdown formatting.
Resume:
{resume_text}
Available Jobs:
{df.to_string(index=False)}
"""
try:
response = groq_client.chat.completions.create(
model="llama3-8b-8192",
messages=[{"role": "user", "content": prompt}]
)
message = response.choices[0].message.content.strip()
if not message:
st.error("β Groq returned an empty response.")
else:
st.success("β
Analysis Complete!")
# Output full analysis
st.markdown(message, unsafe_allow_html=True)
# Job recommendations
st.markdown("---")
st.subheader("π Job Listing Overview")
st.dataframe(df)
# Call-to-action
st.markdown("### π Unlock More Features or Take Action")
col1, col2 = st.columns(2)
with col1:
if st.button("β
Apply Now"):
st.info("π Redirecting to application portal... (hook this into your system)")
with col2:
if st.button("π Upgrade to Pro Templates"):
st.warning("Premium templates coming soon! Contact support to activate.")
except Exception as e:
st.error(f"β Failed to generate analysis: {e}") |