Spaces:
Sleeping
Sleeping
import os | |
import json | |
import requests | |
import streamlit as st | |
from datetime import datetime | |
from docx import Document | |
from PyPDF2 import PdfReader | |
# ------------------------------------------------------------------------------ | |
# π CONFIGURATION - API & SETTINGS | |
# ------------------------------------------------------------------------------ | |
GROQ_API_KEY = os.getenv("GROQ_API") | |
GROQ_ENDPOINT = "https://api.groq.com/openai/v1/chat/completions" | |
GROQ_MODEL = "llama-3.3-70b-versatile" | |
# ------------------------------------------------------------------------------ | |
# π₯ ADVANCED API CALL FUNCTION | |
# ------------------------------------------------------------------------------ | |
def call_groq_api(messages, temperature=0.7): | |
"""Handles API calls to Groq for chat-based completions with robust error handling.""" | |
headers = { | |
"Authorization": f"Bearer {GROQ_API_KEY}", | |
"Content-Type": "application/json" | |
} | |
payload = { | |
"model": GROQ_MODEL, | |
"messages": messages, | |
"temperature": temperature, | |
"max_tokens": 1024 | |
} | |
try: | |
response = requests.post(GROQ_ENDPOINT, headers=headers, json=payload, timeout=15) | |
response.raise_for_status() | |
return response.json()["choices"][0]["message"]["content"].strip() | |
except requests.exceptions.RequestException as e: | |
st.error(f"β API Request Failed: {e}") | |
return None | |
# ------------------------------------------------------------------------------ | |
# π FILE PROCESSING (PDF / DOCX) | |
# ------------------------------------------------------------------------------ | |
def extract_resume_text(file_obj): | |
"""Extracts text from PDF or DOCX resumes.""" | |
file_bytes = file_obj.read() | |
file_obj.seek(0) | |
ext = os.path.splitext(file_obj.name)[-1].lower() | |
if ext == ".pdf": | |
return "\n".join(page.extract_text() for page in PdfReader(file_bytes).pages if page.extract_text()) | |
elif ext in [".docx", ".doc"]: | |
return "\n".join([para.text for para in Document(file_bytes).paragraphs]) | |
else: | |
return file_bytes.decode("utf-8", errors="ignore") | |
# ------------------------------------------------------------------------------ | |
# π― AI-Powered Resume Parsing | |
# ------------------------------------------------------------------------------ | |
def parse_resume(resume_text): | |
"""Extracts structured JSON resume details using Groq's Llama 3.3 model.""" | |
messages = [ | |
{"role": "system", "content": "You are a resume parsing expert. Extract structured data."}, | |
{"role": "user", "content": f"Extract structured data from this resume:\n{resume_text}\n\nOutput as JSON."} | |
] | |
return call_groq_api(messages, temperature=0.4) | |
# ------------------------------------------------------------------------------ | |
# βοΈ AI-Powered Cover Letter Generator | |
# ------------------------------------------------------------------------------ | |
def generate_cover_letter(candidate_json, job_description): | |
"""Generates a professional cover letter using structured candidate data.""" | |
date_str = datetime.today().strftime("%d - %b - %Y") | |
messages = [ | |
{"role": "system", "content": "You are a top-tier career advisor. Write persuasive cover letters."}, | |
{"role": "user", "content": f""" | |
Generate a professional cover letter using: | |
- Candidate Profile: {candidate_json} | |
- Job Description: {job_description} | |
- Date: {date_str} | |
The cover letter should be engaging, personalized, and formatted professionally. | |
"""} | |
] | |
return call_groq_api(messages, temperature=0.5) | |
# ------------------------------------------------------------------------------ | |
# π AI-Powered Resume Creator | |
# ------------------------------------------------------------------------------ | |
def generate_resume(first_name, last_name, location, work_experience, school_experience, skills): | |
"""Generates a well-formatted professional resume.""" | |
candidate_data = json.dumps({ | |
"first_name": first_name, | |
"last_name": last_name, | |
"location": location, | |
"work_experience": work_experience, | |
"school_experience": school_experience, | |
"skills": skills | |
}, indent=2) | |
messages = [ | |
{"role": "system", "content": "You are a professional resume writer."}, | |
{"role": "user", "content": f""" | |
Create a structured, ATS-friendly resume using: | |
{candidate_data} | |
Ensure: | |
- Clear sections (Personal Info, Experience, Education, Skills) | |
- Professional formatting | |
- A compelling summary if possible. | |
"""} | |
] | |
return call_groq_api(messages, temperature=0.5) | |
# ------------------------------------------------------------------------------ | |
# π¨ STREAMLIT UI DESIGN | |
# ------------------------------------------------------------------------------ | |
st.set_page_config(page_title="AI-Powered Job Assistant", layout="wide") | |
st.title("π AI-Powered Resume & Cover Letter Generator") | |
st.markdown("#### Generate a **Resume** or a **Cover Letter** using **Llama 3.3-70B** powered by **Groq AI**.") | |
tabs = st.tabs(["π Cover Letter Generator", "π Resume Creator"]) | |
# ----- COVER LETTER GENERATOR ----- | |
with tabs[0]: | |
st.header("π Cover Letter Generator") | |
resume_file = st.file_uploader("Upload Your Resume", type=["pdf", "docx", "txt"]) | |
job_description = st.text_area("Paste Job Description", height=200) | |
if st.button("πΉ Generate Cover Letter"): | |
if resume_file and job_description.strip(): | |
with st.spinner("β¨ Processing resume..."): | |
resume_text = extract_resume_text(resume_file) | |
candidate_json = parse_resume(resume_text) | |
cover_letter = generate_cover_letter(candidate_json, job_description) | |
st.success("β Cover Letter Generated!") | |
st.text_area("π Your Cover Letter:", cover_letter, height=300) | |
else: | |
st.warning("β οΈ Please upload a resume and paste the job description.") | |
# ----- RESUME CREATOR ----- | |
with tabs[1]: | |
st.header("π Resume Creator") | |
with st.form("resume_form"): | |
col1, col2 = st.columns(2) | |
first_name = col1.text_input("First Name") | |
last_name = col2.text_input("Last Name") | |
location = st.text_input("Location") | |
work_experience = st.text_area("Work Experience", height=150) | |
school_experience = st.text_area("Education", height=150) | |
skills = st.text_area("Skills", height=100) | |
submit = st.form_submit_button("π Generate Resume") | |
if submit: | |
with st.spinner("π Creating Resume..."): | |
resume_text = generate_resume(first_name, last_name, location, work_experience, school_experience, skills) | |
st.success("β Resume Generated!") | |
st.text_area("π Your Resume:", resume_text, height=400) | |