Spaces:
Sleeping
Sleeping
Enhance .gitignore to include additional Python, environment, IDE, and model file exclusions. Refactor app.py to improve text generation pipeline initialization with better error handling and enhanced prompt structure for email generation. Update requirements.txt to specify minimum versions for dependencies, ensuring compatibility and stability.
10493d1
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 | |
import os | |
# 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") | |
# 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: | |
def initialize_pipeline(access_token): | |
try: | |
tokenizer = AutoTokenizer.from_pretrained("google/gemma-2b-it", token=access_token) | |
model = AutoModelForCausalLM.from_pretrained( | |
"google/gemma-2b-it", | |
token=access_token, | |
device_map="auto" # Better device handling | |
) | |
return pipeline( | |
"text-generation", | |
model=model, | |
tokenizer=tokenizer, | |
max_new_tokens=512, | |
temperature=0.7, # Add temperature for better generation | |
do_sample=True, # Enable sampling | |
top_p=0.95 # Add top_p for better text quality | |
) | |
except Exception as e: | |
st.error(f"Failed to initialize the model: {str(e)}") | |
return None | |
text_gen_pipeline = initialize_pipeline(access_token) | |
def initialize_memory(): | |
return ConversationBufferMemory( | |
input_key="input", | |
output_key="output", | |
return_messages=True | |
) | |
# 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(): | |
try: | |
memory = initialize_memory() | |
# Improved prompt template | |
prompt = f"""Task: Write a professional job application email. | |
CV Summary: | |
{st.session_state.parsed_cv} | |
Job Description: | |
{job_description} | |
Instructions: Write a concise and professional email expressing interest in the position. | |
Highlight relevant experience and skills from the CV that match the job requirements. | |
Keep the tone professional and enthusiastic. | |
Email: | |
""" | |
# Generate email using the pipeline | |
if text_gen_pipeline: | |
response = text_gen_pipeline( | |
prompt, | |
clean_up_tokenization_spaces=True, | |
return_full_text=False | |
)[0]['generated_text'] | |
# Store in memory | |
memory.save_context( | |
{"input": f"Job Description: {job_description}"}, | |
{"output": response} | |
) | |
# Display response | |
st.subheader("Generated Email:") | |
st.write(response) | |
# Display conversation history | |
st.subheader("Previous Generations:") | |
for entry in memory.load_memory_variables({})['history']: | |
st.write(entry) | |
else: | |
st.error("Text generation pipeline not properly initialized.") | |
except Exception as e: | |
st.error(f"Error generating email: {str(e)}") | |
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.") | |