| !pip install PyMuPDF |
| !pip install python-docx |
| !pip install crewai crewai-tools |
| !pip streamlit |
|
|
| |
| import warnings |
| warnings.filterwarnings('ignore') |
|
|
|
|
| import fitz |
| import docx |
| from crewai_tools import SerperDevTool |
| import os |
| from crewai import Agent, Task, Crew |
| from dotenv import load_dotenv |
| import tempfile |
|
|
| |
| load_dotenv() |
|
|
| |
| import streamlit as st |
|
|
| |
| st.set_page_config(page_title="Smart Resume Analyzer", layout="wide") |
|
|
| |
| st.markdown( |
| f""" |
| <style> |
| .stApp {{ |
| background-color: #50a7c7; |
| }} |
| .title-text {{ |
| font-size: 1000px; /* Increased font size */ |
| font-weight: bold; |
| color: white; |
| text-align: center; |
| margin-bottom: 20px; |
| }} |
| .subtitle-text {{ |
| font-style: italic; |
| color: white; |
| text-align: center; |
| margin-bottom: 30px; |
| }} |
| .upload-box {{ |
| border: 2px dashed #ffffff; |
| padding: 20px; |
| text-align: center; |
| background-color: rgba(255, 255, 255, 0.2); |
| border-radius: 10px; |
| margin: 0 auto; |
| width: 50%; /* Reduced width of the upload box */ |
| }} |
| .stTextInput input {{ |
| max-width: 300px; /* Reduced width of the text input */ |
| }} |
| </style> |
| """, |
| unsafe_allow_html=True |
| ) |
|
|
| |
| st.markdown('<p class="title-text">Smart Resume Analyzer & Job Matcher</p>', unsafe_allow_html=True) |
| st.markdown('<p class="subtitle-text">Expected Runtime: 1 Min</p>', unsafe_allow_html=True) |
|
|
| |
| st.markdown("### Upload Your Resume (PDF or DOCX)") |
| uploaded_file = st.file_uploader("Drop File Here or Click to Upload", type=["pdf", "docx"], help="Upload your resume for analysis.",key="resume_upload") |
|
|
| |
| preferred_location = st.text_input("Preferred Location", placeholder="e.g., San Francisco",max_chars=50, key="location_input") |
|
|
|
|
| |
|
|
| |
| submit_button = st.button("Submit",icon="😃") |
|
|
| |
| def extract_text_from_pdf(file_path): |
| """Extracts text from a PDF file using PyMuPDF.""" |
| doc = fitz.open(file_path) |
| text = "" |
| for page in doc: |
| text += page.get_text() |
| return text |
|
|
| |
| def extract_text_from_docx(file_path): |
| """Extracts text from a DOCX file using python-docx.""" |
| doc = docx.Document(file_path) |
| fullText = [] |
| for para in doc.paragraphs: |
| fullText.append(para.text) |
| return "\n".join(fullText) |
|
|
| |
| def extract_text_from_resume(file_path): |
| """Determines file type and extracts text.""" |
| if file_path.endswith(".pdf"): |
| return extract_text_from_pdf(file_path) |
| elif file_path.endswith(".docx"): |
| return extract_text_from_docx(file_path) |
| else: |
| return "Unsupported file format." |
|
|
| |
| def initialize_crew(): |
| search_tool = SerperDevTool() |
|
|
| |
| resume_advisor = Agent( |
| role="Professional Resume Advisor", |
| goal="Give feedback on the resume to make it stand out in the job market.", |
| verbose=True, |
| backstory="With a strategic mind and an eye for detail, you excel at providing feedback on resumes to highlight the most relevant skills and experiences." |
| ) |
|
|
| |
| resume_writer = Agent( |
| role="Professional Resume Writer", |
| goal="Based on the feedback received from Resume Advisor, make changes to the resume to make it stand out in the job market.", |
| verbose=True, |
| backstory="With a strategic mind and an eye for detail, you excel at refining resumes based on the feedback to highlight the most relevant skills and experiences." |
| ) |
|
|
| |
| job_researcher = Agent( |
| role="Senior Recruitment Consultant", |
| goal="Find the 5 most relevant, recently posted jobs based on the improved resume received from resume advisor and the location preference.", |
| tools=[search_tool], |
| verbose=True, |
| backstory="""As a senior recruitment consultant, your prowess in finding the most relevant jobs based on the resume and location preference is unmatched. |
| You can scan the resume efficiently, identify the most suitable job roles, and search for the best-suited recently posted open job positions at the preferred location.""" |
| ) |
|
|
| |
| resume_advisor_task = Task( |
| description=( |
| """Give feedback on the resume to make it stand out for recruiters. |
| Review every section, including the summary, work experience, skills, and education. Suggest to add relevant sections if they are missing. |
| Also, give an overall score to the resume out of 10. This is the resume: {resume}""" |
| ), |
| expected_output="The overall score of the resume followed by the feedback in bullet points.", |
| agent=resume_advisor |
| ) |
|
|
| |
| resume_writer_task = Task( |
| description=( |
| """Rewrite the resume based on the feedback to make it stand out for recruiters. You can adjust and enhance the resume but don't make up facts. |
| Review and update every section, including the summary, work experience, skills, and education to better reflect the candidate's abilities. This is the resume: {resume}""" |
| ), |
| expected_output="Resume in markdown format that effectively highlights the candidate's qualifications and experiences.", |
| context=[resume_advisor_task], |
| agent=resume_writer |
| ) |
|
|
| |
| research_task = Task( |
| description="""Find the 5 most relevant recent job postings based on the resume received from resume advisor and location preference. This is the preferred location: {location}. |
| Use the tools to gather relevant content and shortlist the 5 most relevant, recent, job openings.""", |
| expected_output="A bullet point list of the 5 job openings, with the appropriate links and detailed description about each job, in markdown format.", |
| agent=job_researcher |
| ) |
|
|
| |
| crew = Crew( |
| name="Resume Analysis Crew", |
| tasks=[resume_advisor_task, resume_writer_task, research_task], |
| agents=[resume_advisor, resume_writer, job_researcher] |
| ) |
|
|
| return crew,resume_advisor_task, resume_writer_task, research_task |
|
|
|
|
| |
| def resume_agent(file_path, location): |
| resume_text = extract_text_from_resume(file_path) |
|
|
| crew, resume_advisor_task, resume_writer_task, research_task = initialize_crew() |
| result = crew.kickoff(inputs={"resume": resume_text, "location": location}) |
|
|
| |
| feedback = resume_advisor_task.output.raw.strip("```markdown").strip("```").strip() |
| improved_resume = resume_writer_task.output.raw.strip("```markdown").strip("```").strip() |
| job_roles = research_task.output.raw.strip("```markdown").strip("```").strip() |
|
|
| return feedback, improved_resume, job_roles |
|
|
| |
| if submit_button: |
| if uploaded_file is None: |
| st.error("Please upload a resume before submitting.") |
| else: |
| with st.spinner("Analyzing your resume and finding job matches..."): |
| |
| with tempfile.NamedTemporaryFile(delete=False, suffix=os.path.splitext(uploaded_file.name)[1]) as tmp_file: |
| tmp_file.write(uploaded_file.getvalue()) |
| tmp_file_path = tmp_file.name |
|
|
| try: |
| feedback, improved_resume, job_roles = resume_agent(tmp_file_path, preferred_location) |
| |
| st.success("Analysis complete!") |
| st.markdown("## Resume Feedback:") |
| st.markdown(feedback) |
| |
| st.markdown("## Improved Resume Suggestions:") |
| st.markdown(improved_resume) |
| |
| st.markdown("## Relevant Job Roles:") |
| st.markdown(job_roles) |
| except Exception as e: |
| st.error(f"An error occurred: {e}") |
| finally: |
| |
| os.unlink(tmp_file_path) |