Spaces:
Sleeping
Sleeping
File size: 6,629 Bytes
38c327b b82d535 1142c0d 38c327b 1142c0d 38c327b b82d535 1142c0d b82d535 1142c0d 30543fe 1142c0d 30543fe b82d535 1142c0d b82d535 1142c0d 38c327b 1142c0d 38c327b 1142c0d 30543fe 38c327b 1142c0d 38c327b 1142c0d 38c327b 1142c0d 38c327b 1142c0d 38c327b 30543fe 1142c0d 30543fe 1142c0d 38c327b 1142c0d 30543fe 1142c0d 30543fe 1142c0d 30543fe 1142c0d 38c327b 30543fe 38c327b 1142c0d 38c327b 30543fe 1142c0d 30543fe 38c327b 1142c0d 38c327b 1142c0d 38c327b 1142c0d 30543fe 1142c0d 38c327b 30543fe 1142c0d 38c327b 1142c0d 38c327b 1142c0d 38c327b 1142c0d 38c327b 1142c0d |
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 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"
# ------------------------------------------------------------------------------
# π₯ API HANDLER FOR GROQ AI
# ------------------------------------------------------------------------------
def call_groq_api(messages, temperature=0.7):
"""Handles API calls to Groq's Llama 3.3 model 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 uploaded resumes (PDF, DOCX, TXT)."""
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 GENERATION
# ------------------------------------------------------------------------------
def generate_resume(first_name, last_name, location, work_experience, school_experience, skills):
"""Generates a structured, ATS-friendly 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 specializing in ATS optimization."},
{"role": "user", "content": f"""
Generate a **highly professional**, **ATS-optimized resume** using the following structured information:
{candidate_data}
- Ensure proper formatting: Name, Contact, Summary, Experience, Education, Skills, Certifications.
- Use industry best practices.
- Format each job with measurable achievements.
"""}
]
return call_groq_api(messages, temperature=0.5)
# ------------------------------------------------------------------------------
# βοΈ AI-POWERED COVER LETTER GENERATION
# ------------------------------------------------------------------------------
def generate_cover_letter(candidate_json, job_description):
"""Generates a compelling cover letter using structured candidate details."""
date_str = datetime.today().strftime("%d - %b - %Y")
messages = [
{"role": "system", "content": "You are a top-tier career advisor. Write highly persuasive cover letters."},
{"role": "user", "content": f"""
Generate a **professional cover letter** using:
- Candidate Profile: {candidate_json}
- Job Description: {job_description}
- Date: {date_str}
- Ensure **persuasion**, **tailored content**, and **measurable achievements**.
- Format: **Introduction, Key Skills, Experience Alignment, Closing**.
"""}
]
return call_groq_api(messages, temperature=0.6)
# ------------------------------------------------------------------------------
# π¨ STREAMLIT UI DESIGN
# ------------------------------------------------------------------------------
st.set_page_config(page_title="AI Resume & Cover Letter Generator", layout="wide")
st.title("π AI-Powered Resume & Cover Letter Generator")
st.markdown("### Create a **perfect ATS-friendly Resume** and **tailored Cover Letter** using **Groq AI (Llama 3.3-70B)**")
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 = generate_resume("First", "Last", "Houston, TX", "Experience", "Education", "Skills")
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)
|