Alexvatti's picture
Update app.py
782310c verified
import streamlit as st
import os
from langchain_openai import ChatOpenAI
from crewai import Agent, Task, Crew
import PyPDF2
from docx import Document
# Load environment variables
api_key = os.getenv("OPENAI_API_KEY")
os.environ["OPENAI_API_KEY"] = api_key
# Initialize LLM
llm = ChatOpenAI(
model_name="gpt-4o-mini", # Not "gpt-4o-mini", valid model names are "gpt-4o", "gpt-4-turbo", "gpt-3.5-turbo"
temperature=0,
openai_api_key=os.getenv("OPENAI_API_KEY")
)
# Function to extract text from resume files
def extract_text_from_file(file):
text = ""
if file.type == "application/pdf":
pdf_reader = PyPDF2.PdfReader(file)
for page in pdf_reader.pages:
text += page.extract_text() + "\n"
elif file.type in ["application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/msword"]:
doc = Document(file)
for para in doc.paragraphs:
text += para.text + "\n"
return text
# Define Agents
resume_agent = Agent(
role="Resume Keyword Extractor",
goal="Extract important skills and keywords from resumes",
backstory="An advanced ATS system that extracts relevant technical skills, tools, programming languages, and certifications from resumes for recruiters.",
verbose=True,
llm=llm # Make sure llm is initialized before this
)
jd_agent = Agent(
role="Job Description Analyzer",
goal="Extract key skills and responsibilities from job descriptions",
backstory="An AI hiring assistant that understands job requirements",
verbose=True,
llm=llm
)
match_agent = Agent(
role="Resume & JD Matcher",
goal="Compare resume with job description and provide a match score",
backstory="An AI that evaluates job fit based on ATS criteria",
verbose=True,
llm=llm
)
st.title("๐Ÿ” AI-Powered ATS Scanner")
st.subheader("โš™๏ธ Resume & JD Match Analysis")
resume_files = st.file_uploader("Upload Resumes (PDF/DOC)", type=["pdf", "docx"], accept_multiple_files=True, key="match_resume")
job_description = st.text_area("Paste Job Description", key="match_jd")
if st.button("Analyze Match"):
if resume_files and job_description:
results = []
for resume_file in resume_files:
resume_text = extract_text_from_file(resume_file)
task_match = Task(
description=f"""Given the following resume text and job description:\n\nResume:\n{resume_text}\n\n
Job Description:\n{job_description}\n\n
Analyze and compare the skills, tools, technologies, and certifications mentioned in both.
Calculate a match score (in percentage) based on the overlap of technical and domain-specific skills.
Additionally, list the important technical skills or certifications mentioned in the Job Description but missing in the Resume.
Do NOT consider soft skills, personality traits, or general statements in the comparison.
Provide the output in this format:
- Match Score: XX%
- Missing Keywords: [List of missing keywords]
""",
agent=match_agent,
expected_output="Match score and missing keywords"
)
crew = Crew(
agents=[match_agent],
tasks=[task_match],
verbose=False
)
result = crew.kickoff(inputs={"resume_text": resume_text, "job_description": job_description})
extracted_keywords = result.tasks_output[0].raw
# Parse result
match_score_line = next((line for line in extracted_keywords.split('\n') if "Match Score" in line), "")
missing_keywords_line = next((line for line in extracted_keywords.split('\n') if "Missing Keywords" in line), "")
try:
score = int(match_score_line.split(":")[1].strip().replace("%", ""))
except:
score = 0
results.append({
"Resume": resume_file.name,
"Match Score (%)": score,
"Missing Keywords": missing_keywords_line.split(":", 1)[-1].strip()
})
# Sort by Match Score descending
results_sorted = sorted(results, key=lambda x: x["Match Score (%)"], reverse=True)
st.success("โœ… ATS Match Results Table")
st.dataframe(results_sorted)
else:
st.warning("Please upload at least one resume and paste the job description.")