File size: 6,914 Bytes
38c327b
 
b82d535
1142c0d
 
38c327b
 
 
 
1142c0d
38c327b
b82d535
1142c0d
 
b82d535
1142c0d
 
 
 
 
b82d535
 
 
 
 
1142c0d
 
 
 
b82d535
1142c0d
 
 
 
 
 
 
38c327b
 
1142c0d
38c327b
1142c0d
 
38c327b
1142c0d
 
38c327b
 
1142c0d
38c327b
1142c0d
38c327b
1142c0d
38c327b
 
1142c0d
38c327b
1142c0d
 
 
 
 
 
 
38c327b
1142c0d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38c327b
 
 
 
 
1142c0d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38c327b
 
1142c0d
38c327b
1142c0d
 
 
38c327b
1142c0d
38c327b
1142c0d
38c327b
1142c0d
 
 
 
 
 
 
38c327b
 
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
149
150
151
152
153
154
155
156
157
158
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)