Spaces:
Sleeping
Sleeping
File size: 5,491 Bytes
5585470 81dcac9 5585470 81dcac9 9d0f36f 81dcac9 | 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 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | import streamlit as st
from langchain_groq import ChatGroq
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from PyPDF2 import PdfReader
@st.cache_resource(show_spinner=False)
def load_llm():
llm = ChatGroq(
temperature=0,
groq_api_key='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',
model_name="llama-3.3-70b-versatile"
)
parser = JsonOutputParser()
return llm, parser
llm, json_parser = load_llm()
if "llm_loaded" not in st.session_state:
st.toast("✅ LLM Loaded Successfully", icon="🤖")
st.session_state.llm_loaded = True
def scrape_job_data(url):
try:
loader = WebBaseLoader(url)
data = loader.load().pop().page_content
return data.strip()
except Exception as e:
return f"Error fetching data: {e}"
def read_resume(uploaded_file):
if uploaded_file.name.endswith(".pdf"):
reader = PdfReader(uploaded_file)
text = "\n".join([page.extract_text() for page in reader.pages if page.extract_text()])
elif uploaded_file.name.endswith(".txt"):
text = uploaded_file.read().decode("utf-8")
else:
text = ""
return text.strip()
def get_job_desc_json(data):
template = PromptTemplate.from_template(
"""
### SCRAPED DATA FROM WEBSITE:
{data}
### INSTRUCTIONS:
The scraped text is from the careers page of a website.
Extract job postings and return valid JSON containing:
'role', 'experience', 'skills', and 'description'.
### VALID JSON (NO PREAMBLE):
"""
)
chain = template | llm
response = chain.invoke({"data": data})
return json_parser.parse(response.content)
def get_resume_json(data):
template = PromptTemplate.from_template(
"""
### SCRAPED DATA FROM RESUME:
{resume_data}
### INSTRUCTIONS:
Extract and return valid JSON containing:
'name', 'about', 'role', 'experience', 'skills', 'projects', 'courses', and 'certificate'.
### VALID JSON (NO PREAMBLE):
"""
)
chain = template | llm
response = chain.invoke({"resume_data": data})
return json_parser.parse(response.content)
def get_cold_email(job, resume):
template = PromptTemplate.from_template(
"""
### JOB DESCRIPTION:
{job}
### RESUME:
{resume}
### INSTRUCTION:
You are the candidate described in the resume.
Write a concise, personalized cold email to the hiring manager expressing interest in the position.
- Highlight relevant skills and experiences.
- Maintain a professional yet approachable tone.
- Avoid generic phrases; make it sound natural and tailored.
- Keep it under 300-400 words.
### EMAIL (NO PREAMBLE):
"""
)
chain = template | llm
response = chain.invoke({"job": job, "resume": resume})
return response.content.strip()
# ---------------------------------------------------------
# STREAMLIT APP UI
# ---------------------------------------------------------
st.markdown("""
# **⚡ NeoPitch** ✉️
#### "Turn job descriptions and your resume into perfect cold emails in seconds!"
""")
st.markdown("---")
st.subheader("1️⃣ Job Description")
job_input_method = st.radio("How would you like to provide the job info?", ["Paste Text", "Enter URL"])
if "job_description" not in st.session_state:
st.session_state.job_description = ""
if job_input_method == "Paste Text":
st.session_state.job_description = st.text_area(
"Paste Job Description Here 📄",
value=st.session_state.job_description,
height=150,
)
else:
url = st.text_input("Enter Job URL 🌐")
if st.button("Fetch Job Description"):
with st.spinner("Scraping job data... 🔍"):
st.session_state.job_description = scrape_job_data(url)
st.text_area(
"Fetched Job Description 📝",
st.session_state.job_description,
height=150,
)
st.markdown("---")
st.subheader("2️⃣ Resume Input")
resume_input_method = st.radio("How would you like to provide your resume?", ["Upload File", "Paste Text"])
if "resume_data" not in st.session_state:
st.session_state.resume_data = ""
if resume_input_method == "Upload File":
uploaded_file = st.file_uploader("Upload Resume (PDF or TXT) 📎", type=["pdf", "txt"])
if uploaded_file:
st.session_state.resume_data = read_resume(uploaded_file)
else:
st.session_state.resume_data = st.text_area(
"Paste Resume Content Here 📝",
value=st.session_state.resume_data,
height=150,
)
st.markdown("---")
if st.button("🚀 Generate Email"):
if not st.session_state.job_description.strip() or not st.session_state.resume_data.strip():
st.warning("⚠️ Please provide both Job Description and Resume details.")
else:
with st.spinner("Analyzing and generating email... 🤖"):
job = get_job_desc_json(st.session_state.job_description)
resume = get_resume_json(st.session_state.resume_data)
email = get_cold_email(job, resume)
st.success("✅ Email Generated Successfully!")
st.code(email, language="text")
st.download_button("📋 Copy Email", email, file_name="cold_email.txt") |