datascientist22's picture
Create app.py
3822987 verified
raw
history blame
7.81 kB
import pysqlite3
import sys
sys.modules["sqlite3"] = sys.modules.pop("pysqlite3")
import streamlit as st
from uuid import uuid4
from langchain_cohere import CohereEmbeddings
from langchain_chroma import Chroma
from langchain_core.documents import Document
from langchain_cohere import ChatCohere
import random
# Streamlit app
st.set_page_config(page_title="JobFit CV/Resume Matcher πŸ’Ό", page_icon="πŸ’Ό", layout="wide")
# Sidebar design
def apply_sidebar_colors():
st.markdown(
"""
<style>
.sidebar .sidebar-content {
background: linear-gradient(45deg, #ff6f61, #ffcc33, #6f9dff, #93f5a3);
color: white;
}
</style>
""",
unsafe_allow_html=True
)
apply_sidebar_colors()
# App title with emojis
st.title("πŸ’Ό JobFit CV/Resume Matcher")
# Sidebar for API key, job description, and user details
with st.sidebar:
st.header("πŸ”‘ Enter Your Details")
with st.form(key="user_details_form", clear_on_submit=True):
# Field for API key
st.subheader("🌐 Cohere API Key")
st.markdown("You can get your API key from [Cohere's website](https://dashboard.cohere.com/).")
api_key = st.text_input("Enter your Cohere API Key", type="password")
# Job description input
st.subheader("πŸ“ Job Description")
job_description = st.text_area("Paste the Job Description here", placeholder="Enter the job description you're applying for...")
# Check if user data is already in session state
if "name" not in st.session_state:
st.session_state["name"] = ""
if "contact" not in st.session_state:
st.session_state["contact"] = ""
if "user_id" not in st.session_state:
st.session_state["user_id"] = str(random.randint(1000000000, 9999999999))
user_id = st.session_state["user_id"]
# User details inputs
st.subheader("πŸ‘€ Personal Information")
name = st.text_input("Name", st.session_state["name"], placeholder="Enter your full name...")
contact = st.text_input("Contact Information", st.session_state["contact"], placeholder="Email, phone number, or LinkedIn...")
st.subheader("πŸ’Ό Professional Background")
skills = st.text_area("Skills", placeholder="List your skills (one per line)...")
experience = st.text_area("Experience", placeholder="Work experience details (one per line)...")
education = st.text_area("Education", placeholder="Educational qualifications (one per line)...")
projects = st.text_area("Projects", placeholder="Notable projects (one per line)...")
submit_button = st.form_submit_button(label="Save Details")
# Save the data if all fields are filled
if submit_button:
if all([api_key, job_description, name, contact, skills, experience, education, projects]):
st.session_state["api_key"] = api_key
st.session_state["name"] = name
st.session_state["contact"] = contact
st.session_state["job_description"] = job_description
st.session_state["skills"] = skills
st.session_state["experience"] = experience
st.session_state["education"] = education
st.session_state["projects"] = projects
st.success("βœ… Details Saved Successfully!")
else:
st.warning("⚠️ Please fill out all fields to proceed.")
# Check if the user has saved the details
if "api_key" in st.session_state:
# Main layout for generating the resume
st.subheader("πŸ› οΈ Generate Your Custom Resume")
# Convert input fields to lists
skills_list = st.session_state["skills"].splitlines()
experience_list = st.session_state["experience"].splitlines()
education_list = st.session_state["education"].splitlines()
project_list = st.session_state["projects"].splitlines()
# Initialize embeddings and vector store
embedding_model = CohereEmbeddings(cohere_api_key=st.session_state["api_key"], model="embed-english-light-v3.0")
vector_store = Chroma(collection_name="user_data", embedding_function=embedding_model, persist_directory="chroma")
# Create documents for vector store
skill_documents = [Document(page_content=skill, metadata={"user_id": user_id, "type": "skill"}, id=str(uuid4())) for skill in skills_list]
experience_documents = [Document(page_content=exp, metadata={"user_id": user_id, "type": "experience"}, id=str(uuid4())) for exp in experience_list]
education_documents = [Document(page_content=edu, metadata={"user_id": user_id, "type": "education"}, id=str(uuid4())) for edu in education_list]
project_documents = [Document(page_content=proj, metadata={"user_id": user_id, "type": "project"}, id=str(uuid4())) for proj in project_list]
# Add documents to the vector store
vector_store.add_documents(skill_documents + experience_documents + education_documents + project_documents)
# Button to generate the resume
if st.button("πŸ“ Generate Resume"):
def remove_duplicates(results):
seen = set()
unique_results = []
for result in results:
if result.page_content not in seen:
unique_results.append(result)
seen.add(result.page_content)
return unique_results
# Search for relevant information based on the job description
relevant_skills = vector_store.similarity_search_by_vector(embedding_model.embed_query(st.session_state["job_description"]), k=10, filter={"type": "skill"})
relevant_experience = vector_store.similarity_search_by_vector(embedding_model.embed_query(st.session_state["job_description"]), k=4, filter={"type": "experience"})
relevant_education = vector_store.similarity_search_by_vector(embedding_model.embed_query(st.session_state["job_description"]), k=4, filter={"type": "education"})
relevant_projects = vector_store.similarity_search_by_vector(embedding_model.embed_query(st.session_state["job_description"]), k=4, filter={"type": "project"})
# Format the results
skills_content = "\n".join([doc.page_content for doc in remove_duplicates(relevant_skills)])
experience_content = "\n".join([doc.page_content for doc in remove_duplicates(relevant_experience)])
education_content = "\n".join([doc.page_content for doc in remove_duplicates(relevant_education)])
projects_content = "\n".join([doc.page_content for doc in remove_duplicates(relevant_projects)])
# Create a prompt to generate the resume
system_prompt = f"""
Generate a well-structured resume for {st.session_state['name']} with the following details:
Job Description: {st.session_state['job_description']}
Name: {st.session_state['name']}
Contact: {st.session_state['contact']}
Skills: {skills_content}
Experience: {experience_content}
Education: {education_content}
Projects: {projects_content}
Follow this structure:
- Name and contact at the top.
- Skills, experience, education, and projects listed clearly.
- Use bullet points and headings where needed.
"""
# Initialize ChatCohere
chat_model = ChatCohere(cohere_api_key=st.session_state["api_key"])
# Generate resume
resume_output = chat_model.invoke(input=system_prompt)
# Display the generated resume and a copy button
st.subheader("πŸ“„ Generated Resume")
st.text_area("Your Resume", resume_output.content, height=400)
st.button("πŸ“‹ Copy Resume to Clipboard")
else:
st.info("πŸ‘ˆ Please enter your details and click Save to generate your resume.")