Spaces:
Runtime error
Runtime error
| import streamlit as st | |
| import tempfile | |
| import os | |
| from pathlib import Path | |
| from PyPDF2 import PdfReader | |
| from openai import OpenAI | |
| # Import our CrewAI resume optimization module. | |
| from crewai_resume_optimization import optimize_resume, generate_interview_questions, extract_job_description | |
| # --------------------------- | |
| # Helper Function: Extract text from PDF (for resume) | |
| # --------------------------- | |
| def extract_pdf_text(uploaded_file): | |
| # Check file size (limit: 10MB) | |
| uploaded_file.seek(0, os.SEEK_END) | |
| if uploaded_file.tell() > 10 * 1024 * 1024: | |
| st.error("File exceeds 10MB limit.") | |
| return "" | |
| uploaded_file.seek(0) | |
| reader = PdfReader(uploaded_file) | |
| text = "" | |
| for page in reader.pages: | |
| page_text = page.extract_text() | |
| if page_text: | |
| text += page_text + "\n" | |
| return text | |
| # --------------------------- | |
| # Sidebar: File Upload & Job Input Mode | |
| # --------------------------- | |
| st.sidebar.title("Upload your resume and add a job description") | |
| # Resume upload (PDF only) | |
| uploaded_resume = st.sidebar.file_uploader("Upload your resume (PDF, max 10MB)", type="pdf") | |
| # Job input mode: "Job Description" vs "Job URL" | |
| job_input_mode = st.sidebar.radio("Select Job Input Mode", ("Job Description", "Job URL")) | |
| job_input = "" | |
| if job_input_mode == "Job Description": | |
| job_input = st.sidebar.text_area("Paste the job description here:") | |
| elif job_input_mode == "Job URL": | |
| job_input = st.sidebar.text_input("Enter the job URL:") | |
| # Button to extract job description if URL mode is selected. | |
| if job_input_mode == "Job URL" and st.sidebar.button("Extract Job Description"): | |
| if job_input: | |
| st.session_state.job_description = extract_job_description(job_input) | |
| st.sidebar.success("Job description extracted!") | |
| else: | |
| st.sidebar.error("Please enter a job URL.") | |
| # For Job Description mode, use the pasted job description. | |
| if job_input_mode == "Job Description": | |
| st.session_state.job_description = job_input | |
| # Button to trigger resume optimization. | |
| if st.sidebar.button("Optimize Resume"): | |
| st.session_state.optimize_trigger = True | |
| # --------------------------- | |
| # Session State Initialization | |
| # --------------------------- | |
| if "resume_text" not in st.session_state: | |
| st.session_state.resume_text = None | |
| if "job_description" not in st.session_state: | |
| st.session_state.job_description = None | |
| if "optimized_resume" not in st.session_state: | |
| st.session_state.optimized_resume = None | |
| if "interview_questions" not in st.session_state: | |
| st.session_state.interview_questions = None | |
| # --------------------------- | |
| # Process Resume Upload | |
| # --------------------------- | |
| if uploaded_resume is not None: | |
| st.session_state.resume_text = extract_pdf_text(uploaded_resume) | |
| if st.session_state.resume_text: | |
| st.sidebar.success("Resume uploaded and processed successfully!") | |
| else: | |
| st.sidebar.error("Failed to extract text from the resume.") | |
| # --------------------------- | |
| # Main Area: Display Results | |
| # --------------------------- | |
| st.title("Resume Optimizer") | |
| if st.session_state.resume_text is None: | |
| st.info("Please upload your resume from the sidebar to begin.") | |
| else: | |
| if st.session_state.job_description: | |
| st.subheader("Job Description") | |
| st.write(st.session_state.job_description) | |
| else: | |
| st.info("Please provide a job description (paste or extract from URL) from the sidebar.") | |
| if st.session_state.get("optimize_trigger", False): | |
| if st.session_state.resume_text and st.session_state.job_description: | |
| with st.spinner("Optimizing resume..."): | |
| st.session_state.optimized_resume = optimize_resume(st.session_state.resume_text, st.session_state.job_description) | |
| with st.spinner("Generating interview questions..."): | |
| st.session_state.interview_questions = generate_interview_questions(st.session_state.optimized_resume, st.session_state.job_description) | |
| st.success("Resume optimized and interview questions generated!") | |
| st.session_state.optimize_trigger = False | |
| else: | |
| st.error("Please ensure you have uploaded your resume and provided a job description.") | |
| if st.session_state.optimized_resume: | |
| st.header("Optimized Resume") | |
| st.markdown(st.session_state.optimized_resume) | |
| st.download_button("Download Optimized Resume (md)", | |
| st.session_state.optimized_resume, | |
| file_name="tailored_resume.md", | |
| mime="text/markdown") | |
| if st.session_state.interview_questions: | |
| st.header("Interview Questions") | |
| st.markdown(st.session_state.interview_questions) | |
| st.download_button("Download Interview Questions (md)", | |
| st.session_state.interview_questions, | |
| file_name="interview_materials.md", | |
| mime="text/markdown") | |
| st.info("You can open the downloaded markdown (.md) files with Notepad or any text editor.") | |