Spaces:
Sleeping
Sleeping
import os | |
import streamlit as st | |
import PyPDF2 | |
from langchain_community.llms import HuggingFaceHub | |
# Streamlit page configuration | |
st.set_page_config(page_title="Research Position Application Generator", page_icon="🔬") | |
# Set Hugging Face API Key | |
os.environ["HUGGINGFACEHUB_API_TOKEN"] = st.secrets["HF_TOKEN"] | |
# Initialize LLM | |
llm = HuggingFaceHub( | |
repo_id="mistralai/Mistral-7B-Instruct-v0.3", | |
model_kwargs={"temperature": 0.5} | |
) | |
def extract_text_from_pdf(uploaded_file): | |
""" | |
Extract text from an uploaded PDF file. | |
Args: | |
uploaded_file (UploadedFile): PDF file uploaded by the user | |
Returns: | |
str: Extracted text from the PDF | |
""" | |
try: | |
pdf_reader = PyPDF2.PdfReader(uploaded_file) | |
text = "" | |
for page in pdf_reader.pages: | |
text += page.extract_text() | |
return text | |
except Exception as e: | |
st.error(f"Error extracting PDF text: {e}") | |
return "" | |
def generate_cold_email(position_details, cv_text): | |
""" | |
Generate a professional cold email using the LLM. | |
Args: | |
position_details (dict): Details about the research position | |
cv_text (str): Text extracted from the CV/resume | |
Returns: | |
str: Generated cold email | |
""" | |
prompt = f"""Write a professional and concise cold email to Professor {position_details['professor_name']} | |
at {position_details['university']} about the research position in {position_details['research_focus']}. | |
The email should: | |
1. Demonstrate knowledge of the professor's research | |
2. Highlight relevant experience from the CV | |
3. Express genuine interest in the position | |
4. Be no more than 250 words | |
CV Details: | |
{cv_text} | |
Research Position Details: | |
Research Focus: {position_details['research_focus']} | |
Professor: {position_details['professor_name']} | |
University: {position_details['university']} | |
""" | |
return llm.invoke(prompt) | |
def generate_cover_letter(position_details, cv_text): | |
""" | |
Generate a formal cover letter using the LLM. | |
Args: | |
position_details (dict): Details about the research position | |
cv_text (str): Text extracted from the CV/resume | |
Returns: | |
str: Generated cover letter | |
""" | |
prompt = f"""Write a professional and formal cover letter for a research position with the following details: | |
Research Focus: {position_details['research_focus']} | |
University: {position_details['university']} | |
The cover letter should: | |
1. Follow a standard business letter format | |
2. Clearly state the purpose of the letter | |
3. Highlight relevant skills and experiences from the CV | |
4. Demonstrate alignment with the research position | |
5. Be 300-400 words long | |
6. Include a strong closing paragraph | |
CV Details: | |
{cv_text} | |
""" | |
return llm.invoke(prompt) | |
def main(): | |
""" | |
Main Streamlit app function | |
""" | |
st.title("🔬 Research Position Application Generator") | |
# Sidebar for position details | |
st.sidebar.header("Research Position Details") | |
professor_name = st.sidebar.text_input("Professor's Name") | |
university = st.sidebar.text_input("University") | |
research_focus = st.sidebar.text_input("Research Focus") | |
# CV Upload | |
st.sidebar.header("Upload CV/Resume") | |
uploaded_cv = st.sidebar.file_uploader("Choose a PDF file", type="pdf") | |
# Generate button | |
if st.sidebar.button("Generate Documents"): | |
# Validate inputs | |
if not (professor_name and university and research_focus and uploaded_cv): | |
st.error("Please fill in all details and upload a CV") | |
return | |
# Extract CV text | |
cv_text = extract_text_from_pdf(uploaded_cv) | |
# Prepare position details | |
position_details = { | |
'professor_name': professor_name, | |
'university': university, | |
'research_focus': research_focus | |
} | |
# Generate documents | |
with st.spinner('Generating documents...'): | |
cold_email = generate_cold_email(position_details, cv_text) | |
cover_letter = generate_cover_letter(position_details, cv_text) | |
# Display results | |
st.header("Generated Documents") | |
# Cold Email | |
st.subheader("Cold Email") | |
st.write(cold_email) | |
st.download_button( | |
label="Download Cold Email", | |
data=cold_email, | |
file_name="cold_email.txt", | |
mime="text/plain" | |
) | |
# Cover Letter | |
st.subheader("Cover Letter") | |
st.write(cover_letter) | |
st.download_button( | |
label="Download Cover Letter", | |
data=cover_letter, | |
file_name="cover_letter.txt", | |
mime="text/plain" | |
) | |
if __name__ == "__main__": | |
main() |