MuhammadQASIM111 commited on
Commit
b004d76
·
verified ·
1 Parent(s): 15d927b

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +176 -0
app.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import warnings
2
+ warnings.filterwarnings('ignore')
3
+
4
+
5
+ import fitz # PyMuPDF for PDF processing
6
+ import docx # python-docx for DOCX processing
7
+ import gradio as gr
8
+ import os
9
+ from crewai import Agent, Task, Crew
10
+ from crewai_tools import SerperDevTool
11
+
12
+
13
+ os.environ['OPENAI_API_KEY'] = os.getenv("openaikey")
14
+ os.environ["OPENAI_MODEL_NAME"] = 'gpt-4o-mini'
15
+ os.environ["SERPER_API_KEY"] = os.getenv("serper_key")
16
+
17
+
18
+
19
+ def extract_text_from_pdf(file_path):
20
+ """Extracts text from a PDF file using PyMuPDF."""
21
+ doc = fitz.open(file_path)
22
+ text = ""
23
+ for page in doc:
24
+ text += page.get_text()
25
+ return text
26
+
27
+ def extract_text_from_docx(file_path):
28
+ """Extracts text from a DOCX file using python-docx."""
29
+ doc = docx.Document(file_path)
30
+ fullText = []
31
+ for para in doc.paragraphs:
32
+ fullText.append(para.text)
33
+ return "\n".join(fullText)
34
+
35
+ def extract_text_from_resume(file_path):
36
+ """Determines file type and extracts text."""
37
+ if file_path.endswith(".pdf"):
38
+ return extract_text_from_pdf(file_path)
39
+ elif file_path.endswith(".docx"):
40
+ return extract_text_from_docx(file_path)
41
+ else:
42
+ return "Unsupported file format."
43
+
44
+
45
+
46
+ # Agent 1: Resume Strategist
47
+ resume_feedback = Agent(
48
+ role="Professional Resume Advisor",
49
+ goal="Give feedback on the resume to make it stand out in the job market.",
50
+ verbose=True,
51
+ 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."
52
+ )
53
+
54
+
55
+ # Task for Resume Strategist Agent: Align Resume with Job Requirements
56
+ resume_feedback_task = Task(
57
+ description=(
58
+ """Give feedback on the resume to make it stand out for recruiters.
59
+ Review every section, inlcuding the summary, work experience, skills, and education. Suggest to add relevant sections if they are missing.
60
+ Also give an overall score to the resume out of 10. This is the resume: {resume}"""
61
+ ),
62
+ expected_output="The overall score of the resume followed by the feedback in bullet points.",
63
+ agent=resume_feedback
64
+ )
65
+
66
+ # Agent 2: Resume Strategist
67
+ resume_advisor = Agent(
68
+ role="Professional Resume Writer",
69
+ goal="Based on the feedback recieved from Resume Advisor, make changes to the resume to make it stand out in the job market.",
70
+ verbose=True,
71
+ 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."
72
+ )
73
+
74
+ # Task for Resume Strategist Agent: Align Resume with Job Requirements
75
+ resume_advisor_task = Task(
76
+ description=(
77
+ """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.
78
+ Review and update every section, including the summary, work experience, skills, and education to better reflect the candidates abilities. This is the resume: {resume}"""
79
+ ),
80
+ expected_output= "Resume in markdown format that effectively highlights the candidate's qualifications and experiences",
81
+ # output_file="improved_resume.md",
82
+ context=[resume_feedback_task],
83
+ agent=resume_advisor
84
+ )
85
+
86
+ search_tool = SerperDevTool()
87
+
88
+
89
+ # Agent 3: Researcher
90
+ job_researcher = Agent(
91
+ role = "Senior Recruitment Consultant",
92
+ goal = "Find the 5 most relevant, recently posted jobs based on the improved resume recieved from resume advisor and the location preference",
93
+ tools = [search_tool],
94
+ verbose = True,
95
+ backstory = """As a senior recruitment consultant your prowess in finding the most relevant jobs based on the resume and location preference is unmatched.
96
+ 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 preffered location."""
97
+ )
98
+
99
+ research_task = Task(
100
+ description = """Find the 5 most relevant recent job postings based on the resume recieved from resume advisor and location preference. This is the preferred location: {location} .
101
+ Use the tools to gather relevant content and shortlist the 5 most relevant, recent, job openings""",
102
+ expected_output=(
103
+ "A bullet point list of the 5 job openings, with the appropriate links and detailed description about each job, in markdown format"
104
+ ),
105
+ # output_file="relevant_jobs.md",
106
+ agent=job_researcher
107
+ )
108
+
109
+
110
+ crew = Crew(
111
+ agents=[resume_feedback, resume_advisor, job_researcher],
112
+ tasks=[resume_feedback_task, resume_advisor_task, research_task],
113
+ verbose=True
114
+ )
115
+
116
+
117
+
118
+ def resume_agent(file_path, location):
119
+ resume_text = extract_text_from_resume(file_path)
120
+
121
+ result = crew.kickoff(inputs={"resume": resume_text, "location": location})
122
+
123
+ # Extract outputs
124
+ feedback = resume_feedback_task.output.raw.strip("```markdown").strip("```").strip()
125
+ improved_resume = resume_advisor_task.output.raw.strip("```markdown").strip("```").strip()
126
+ job_roles = research_task.output.raw.strip("```markdown").strip("```").strip()
127
+
128
+ return feedback, improved_resume, job_roles
129
+
130
+
131
+ # Gradio Interface
132
+ with gr.Blocks() as demo:
133
+ gr.Markdown("# Resume Feedback and Job Matching Tool")
134
+ gr.Markdown("*Expected Runtime: 1 Min*")
135
+
136
+ with gr.Column():
137
+ with gr.Row():
138
+ resume_upload = gr.File(label="Upload Your Resume (PDF or DOCX)", height=120)
139
+ location_input = gr.Textbox(label="Preferred Location", placeholder="e.g., San Francisco")
140
+ submit_button = gr.Button("Submit")
141
+
142
+ with gr.Column():
143
+ feedback_output = gr.Markdown(label="Resume Feedback")
144
+ improved_resume_output = gr.Markdown(label="Improved Resume")
145
+ job_roles_output = gr.Markdown(label="Relevant Job Roles")
146
+
147
+ # Define the click event for the submit button
148
+ def format_outputs(feedback, improved_resume, job_roles):
149
+ # Add bold headings to each section
150
+ feedback_with_heading = f"## Resume Feedback:**\n\n{feedback}"
151
+ improved_resume_with_heading = f"## Improved Resume:\n\n{improved_resume}"
152
+ job_roles_with_heading = f"## Relevant Job Roles:\n\n{job_roles}"
153
+ return feedback_with_heading, improved_resume_with_heading, job_roles_with_heading
154
+
155
+
156
+
157
+ submit_button.click(
158
+ lambda: gr.update(value="Processing..."),
159
+ inputs=[],
160
+ outputs=submit_button
161
+ ).then(
162
+ resume_agent,
163
+ inputs=[resume_upload, location_input],
164
+ outputs=[feedback_output, improved_resume_output, job_roles_output]
165
+ ).then(
166
+ format_outputs,
167
+ inputs=[feedback_output, improved_resume_output, job_roles_output],
168
+ outputs=[feedback_output, improved_resume_output, job_roles_output]
169
+ ).then(
170
+ lambda: gr.update(value="Submit"),
171
+ inputs=[],
172
+ outputs=submit_button
173
+ )
174
+
175
+ demo.queue()
176
+ demo.launch()