File size: 4,297 Bytes
3b9b6a5
d4b8475
 
 
 
3b9b6a5
 
 
 
 
 
d4b8475
3b9b6a5
d4b8475
 
 
 
 
 
3b9b6a5
d4b8475
 
 
 
 
 
3b9b6a5
d4b8475
 
 
 
3b9b6a5
d4b8475
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3b9b6a5
d4b8475
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3b9b6a5
d4b8475
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
import PyPDF2
from dotenv import load_dotenv

# Load environment variables from .env
load_dotenv()

# Job API keys and endpoints
access_token = os.getenv("API_KEY")

# Streamlit App Title
st.title("Job Description and CV-Based Email Generator")
st.write("""
This app uses Hugging Face's Gemma model to generate a professional email based on a pre-parsed CV and a job description.
Upload your CV once in the sidebar, and the system will reuse the parsed details for generating emails.
""")

# Sidebar for Settings and CV Upload
st.sidebar.title("Settings and CV Upload")
access_token = st.sidebar.text_input("Enter your Hugging Face Access Token", type="password")

# File Upload for CV in Sidebar
uploaded_file = st.sidebar.file_uploader("Upload your CV (PDF format):", type=["pdf"])

if "parsed_cv" not in st.session_state:
    st.session_state.parsed_cv = None

if uploaded_file is not None:
    try:
        # Extract text from PDF
        pdf_reader = PyPDF2.PdfReader(uploaded_file)
        cv_text = "".join([page.extract_text() for page in pdf_reader.pages])
        st.sidebar.success("CV uploaded and text extracted successfully!")

        # Parse CV details and save to session state
        def parse_cv(cv_text):
            # Basic parsing logic (can be extended for specific details)
            return f"""
            Name: [Extracted Name]
            Contact Information: [Extracted Contact Info]
            Skills: [Extracted Skills]
            Experience: [Extracted Experience]
            Education: [Extracted Education]
            Summary: {cv_text[:500]}...  # Truncated summary of the CV
            """

        st.session_state.parsed_cv = parse_cv(cv_text)
        st.sidebar.success("CV parsed successfully!")
    except Exception as e:
        st.sidebar.error(f"Failed to extract text from CV: {e}")

if st.session_state.parsed_cv:
    st.sidebar.write("### Parsed CV Details:")
    st.sidebar.text(st.session_state.parsed_cv)

# Ensure Access Token is Provided
if access_token:
    @st.cache_resource
    def initialize_pipeline(access_token):
        tokenizer = AutoTokenizer.from_pretrained("google/gemma-2b-it", token=access_token)
        model = AutoModelForCausalLM.from_pretrained(
            "google/gemma-2b-it",
            torch_dtype="bfloat16",
            token=access_token
        )
        return pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=512)

    text_gen_pipeline = initialize_pipeline(access_token)

    @st.cache_resource
    def initialize_chain():
        memory = ConversationBufferMemory()
        return ConversationChain(llm=None, memory=memory)  # No LLM; handled by pipeline

    conversation_chain = initialize_chain()

    # Input job description
    job_description = st.text_area("Enter the job description:", "")

    # Display generated email
    if st.button("Generate Email"):
        if st.session_state.parsed_cv and job_description.strip():
            # Prompt for email generation
            prompt = (
                f"Based on the following CV details:\n\n{st.session_state.parsed_cv}\n\n"
                f"And the following job description:\n\n{job_description}\n\n"
                f"Write a professional email expressing interest in the job. "
                f"Make it concise, polite, and tailored to the job."
            )

            # Generate email using Hugging Face pipeline
            response = text_gen_pipeline(prompt)[0]['generated_text']

            # Update memory with job description and response
            conversation_chain.memory.save_context({"job_description": job_description}, {"email": response})

            # Display response
            st.subheader("Generated Email:")
            st.write(response)

            # Display conversation history
            st.subheader("History:")
            st.write(conversation_chain.memory.buffer)
        else:
            st.warning("Please upload your CV in the sidebar and enter a job description.")
else:
    st.warning("Please enter your Hugging Face access token in the sidebar to use the app.")