ruslanmv commited on
Commit
3ec605b
·
verified ·
1 Parent(s): b99d884

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -75
app.py CHANGED
@@ -5,19 +5,16 @@ import io
5
  from docx import Document
6
  import os
7
  import pymupdf # Corrected import for PyMuPDF
8
- # For PDF generation
9
  from reportlab.pdfgen import canvas
10
  from reportlab.lib.pagesizes import letter
11
  from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
12
  from reportlab.lib.styles import getSampleStyleSheet
13
  from reportlab.lib import colors
14
 
15
- # Initialize Hugging Face Inference Client with Meta-Llama-3.1-8B-Instruct
16
  client = InferenceClient(
17
  model="meta-llama/Meta-Llama-3-8B-Instruct",
18
  token=os.getenv("HF_TOKEN"))
19
 
20
- # Function to extract text from PDF
21
  def extract_text_from_pdf(pdf_file):
22
  try:
23
  pdf_document = pymupdf.open(pdf_file)
@@ -26,7 +23,6 @@ def extract_text_from_pdf(pdf_file):
26
  except Exception as e:
27
  return f"Error reading PDF: {e}"
28
 
29
- # Function to extract text from DOCX
30
  def extract_text_from_docx(docx_file):
31
  try:
32
  doc = Document(docx_file)
@@ -35,127 +31,85 @@ def extract_text_from_docx(docx_file):
35
  except Exception as e:
36
  return f"Error reading DOCX: {e}"
37
 
38
- # Function to analyze CV
 
 
 
 
 
 
 
39
  def parse_cv(file, job_description):
40
  if file is None:
41
  return "Please upload a CV file.", ""
42
  try:
43
  file_path = file.name
44
  file_ext = os.path.splitext(file_path)[1].lower()
45
- if file_ext == ".pdf":
46
- extracted_text = extract_text_from_pdf(file_path)
47
- elif file_ext == ".docx":
48
- extracted_text = extract_text_from_docx(file_path)
49
- else:
50
- return "Unsupported file format. Please upload a PDF or DOCX file.", ""
51
  except Exception as e:
52
  return f"Error reading file: {e}", ""
53
  if extracted_text.startswith("Error"):
54
- return extracted_text, "Error during text extraction. Please check the file."
55
- prompt = (
56
- f"Analyze the CV against the job description. Provide a summary, assessment, "
57
- f"and a score 0-10.\n\n"
58
- f"Job Description:\n{job_description}\n\n"
59
- f"Candidate CV:\n{extracted_text}\n"
60
- )
61
  try:
62
  analysis = client.text_generation(prompt, max_new_tokens=512)
63
- return extracted_text, f"--- Analysis Report ---\n{analysis}"
64
  except Exception as e:
65
  return extracted_text, f"Analysis Error: {e}"
66
 
67
- # Function to toggle the download button
68
- def toggle_download_button(analysis_report):
69
- return gr.update(interactive=bool(analysis_report.strip()), visible=bool(analysis_report.strip()))
70
-
71
- # Function to create PDF report
72
  def create_pdf_report(report_text):
73
- if not report_text.strip():
74
- report_text = "No analysis report to convert."
75
-
76
  pdf_buffer = io.BytesIO()
77
  doc = SimpleDocTemplate(pdf_buffer, pagesize=letter)
78
  styles = getSampleStyleSheet()
79
- Story = []
80
-
81
- title = Paragraph("<b>Analysis Report</b>", styles['Title'])
82
- Story.append(title)
83
- Story.append(Spacer(1, 12))
84
-
85
- report_paragraph = Paragraph(report_text.replace("\n", "<br/>"), styles['BodyText'])
86
- Story.append(report_paragraph)
87
-
88
  doc.build(Story)
89
  pdf_buffer.seek(0)
90
- return (pdf_buffer.getvalue(), "analysis_report.pdf")
91
 
92
  def process_resume(resume_file, job_title):
93
- """
94
- Processes the uploaded resume, optimizes it for the given job title using the LLM,
95
- and returns the optimized resume content.
96
- """
97
  if resume_file is None:
98
  return "Please upload a resume file."
99
-
100
  try:
101
  file_path = resume_file.name
102
  file_ext = os.path.splitext(file_path)[1].lower()
103
-
104
- if file_ext == ".pdf":
105
- resume_text = extract_text_from_pdf(file_path)
106
- elif file_ext == ".docx":
107
- resume_text = extract_text_from_docx(file_path)
108
- else:
109
- return "Unsupported file format. Please upload a PDF or DOCX file."
110
-
111
  if resume_text.startswith("Error"):
112
  return resume_text
113
-
114
- prompt = (
115
- f"Optimize the following resume for the job title: {job_title}.\n"
116
- f"Include relevant skills, experience, and keywords related to the job title.\n\n"
117
- f"Resume:\n{resume_text}\n"
118
- )
119
-
120
  optimized_resume = client.text_generation(prompt, max_new_tokens=1024)
121
- return optimized_resume
122
-
123
  except Exception as e:
124
  return f"Error processing resume: {e}"
125
- # Build the Gradio UI
126
  demo = gr.Blocks()
127
  with demo:
128
  gr.Markdown("## AI-powered CV Analyzer, Optimizer, and Chatbot")
 
129
  with gr.Tab("Chatbot"):
130
  chat_interface = gr.ChatInterface(
131
- lambda message, history: client.chat_completion(
132
- messages=[{"role": "user", "content": message}],
133
- max_tokens=512,
134
- ),
135
- chatbot=gr.Chatbot(label="Chatbot", type="messages"),
136
  textbox=gr.Textbox(placeholder="Enter your message here...", label="Message"),
137
  )
 
138
  with gr.Tab("CV Analyzer"):
139
- gr.Markdown("### Upload your CV and provide the job description")
140
  file_input = gr.File(label="Upload CV", file_types=[".pdf", ".docx"])
141
  job_desc_input = gr.Textbox(label="Job Description", lines=5)
142
  extracted_text = gr.Textbox(label="Extracted CV Content", lines=10, interactive=False)
143
- analysis_output = gr.Textbox(label="Analysis Report", lines=10, interactive=False)
144
- download_pdf_button = gr.Button("Download Analysis as PDF", visible=False, interactive=False)
145
  pdf_file = gr.File(label="Download PDF", interactive=False)
146
  analyze_button = gr.Button("Analyze CV")
147
-
148
  analyze_button.click(parse_cv, [file_input, job_desc_input], [extracted_text, analysis_output])
149
- analyze_button.click(toggle_download_button, [analysis_output], [download_pdf_button])
150
  download_pdf_button.click(create_pdf_report, [analysis_output], [pdf_file])
 
151
  with gr.Tab("CV Optimizer"):
152
- gr.Markdown("### Upload your Resume and Enter Job Title")
153
  resume_file = gr.File(label="Upload Resume (PDF or Word)", file_types=[".pdf", ".docx"])
154
- job_title_input = gr.Textbox(label="Job Title", lines=1)
155
- optimized_resume_output = gr.Textbox(label="Optimized Resume", lines=20)
156
  optimize_button = gr.Button("Optimize Resume")
157
-
158
  optimize_button.click(process_resume, [resume_file, job_title_input], [optimized_resume_output])
159
 
160
  if __name__ == "__main__":
161
- demo.queue().launch()
 
5
  from docx import Document
6
  import os
7
  import pymupdf # Corrected import for PyMuPDF
 
8
  from reportlab.pdfgen import canvas
9
  from reportlab.lib.pagesizes import letter
10
  from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
11
  from reportlab.lib.styles import getSampleStyleSheet
12
  from reportlab.lib import colors
13
 
 
14
  client = InferenceClient(
15
  model="meta-llama/Meta-Llama-3-8B-Instruct",
16
  token=os.getenv("HF_TOKEN"))
17
 
 
18
  def extract_text_from_pdf(pdf_file):
19
  try:
20
  pdf_document = pymupdf.open(pdf_file)
 
23
  except Exception as e:
24
  return f"Error reading PDF: {e}"
25
 
 
26
  def extract_text_from_docx(docx_file):
27
  try:
28
  doc = Document(docx_file)
 
31
  except Exception as e:
32
  return f"Error reading DOCX: {e}"
33
 
34
+ def chatbot_response(message, history):
35
+ try:
36
+ response = client.text_generation(message, max_new_tokens=512)
37
+ history.append((message, response))
38
+ return "", history # Return empty input and updated history
39
+ except Exception as e:
40
+ return "Error: Unable to generate response.", history
41
+
42
  def parse_cv(file, job_description):
43
  if file is None:
44
  return "Please upload a CV file.", ""
45
  try:
46
  file_path = file.name
47
  file_ext = os.path.splitext(file_path)[1].lower()
48
+ extracted_text = extract_text_from_pdf(file_path) if file_ext == ".pdf" else extract_text_from_docx(file_path)
 
 
 
 
 
49
  except Exception as e:
50
  return f"Error reading file: {e}", ""
51
  if extracted_text.startswith("Error"):
52
+ return extracted_text, "Error during text extraction."
53
+ prompt = f"Analyze this CV for job relevance.\nJob Description:\n{job_description}\n\nCV:\n{extracted_text}\n"
 
 
 
 
 
54
  try:
55
  analysis = client.text_generation(prompt, max_new_tokens=512)
56
+ return extracted_text, f"**Analysis Report:**\n{analysis}"
57
  except Exception as e:
58
  return extracted_text, f"Analysis Error: {e}"
59
 
 
 
 
 
 
60
  def create_pdf_report(report_text):
 
 
 
61
  pdf_buffer = io.BytesIO()
62
  doc = SimpleDocTemplate(pdf_buffer, pagesize=letter)
63
  styles = getSampleStyleSheet()
64
+ Story = [Paragraph("<b>Analysis Report</b>", styles['Title']), Spacer(1, 12)]
65
+ Story.append(Paragraph(report_text.replace("\n", "<br/>"), styles['BodyText']))
 
 
 
 
 
 
 
66
  doc.build(Story)
67
  pdf_buffer.seek(0)
68
+ return pdf_buffer.getvalue(), "analysis_report.pdf"
69
 
70
  def process_resume(resume_file, job_title):
 
 
 
 
71
  if resume_file is None:
72
  return "Please upload a resume file."
 
73
  try:
74
  file_path = resume_file.name
75
  file_ext = os.path.splitext(file_path)[1].lower()
76
+ resume_text = extract_text_from_pdf(file_path) if file_ext == ".pdf" else extract_text_from_docx(file_path)
 
 
 
 
 
 
 
77
  if resume_text.startswith("Error"):
78
  return resume_text
79
+ prompt = f"Optimize this resume for {job_title}:\n{resume_text}\n"
 
 
 
 
 
 
80
  optimized_resume = client.text_generation(prompt, max_new_tokens=1024)
81
+ return optimized_resume.replace("\n", " \n") # Ensure Markdown formatting
 
82
  except Exception as e:
83
  return f"Error processing resume: {e}"
84
+
85
  demo = gr.Blocks()
86
  with demo:
87
  gr.Markdown("## AI-powered CV Analyzer, Optimizer, and Chatbot")
88
+
89
  with gr.Tab("Chatbot"):
90
  chat_interface = gr.ChatInterface(
91
+ chatbot_response,
92
+ chatbot=gr.Chatbot(label="Chatbot"),
 
 
 
93
  textbox=gr.Textbox(placeholder="Enter your message here...", label="Message"),
94
  )
95
+
96
  with gr.Tab("CV Analyzer"):
 
97
  file_input = gr.File(label="Upload CV", file_types=[".pdf", ".docx"])
98
  job_desc_input = gr.Textbox(label="Job Description", lines=5)
99
  extracted_text = gr.Textbox(label="Extracted CV Content", lines=10, interactive=False)
100
+ analysis_output = gr.Markdown(label="Analysis Report")
101
+ download_pdf_button = gr.Button("Download Analysis as PDF", visible=False)
102
  pdf_file = gr.File(label="Download PDF", interactive=False)
103
  analyze_button = gr.Button("Analyze CV")
 
104
  analyze_button.click(parse_cv, [file_input, job_desc_input], [extracted_text, analysis_output])
 
105
  download_pdf_button.click(create_pdf_report, [analysis_output], [pdf_file])
106
+
107
  with gr.Tab("CV Optimizer"):
 
108
  resume_file = gr.File(label="Upload Resume (PDF or Word)", file_types=[".pdf", ".docx"])
109
+ job_title_input = gr.Textbox(label="Job Title")
110
+ optimized_resume_output = gr.Markdown(label="Optimized Resume")
111
  optimize_button = gr.Button("Optimize Resume")
 
112
  optimize_button.click(process_resume, [resume_file, job_title_input], [optimized_resume_output])
113
 
114
  if __name__ == "__main__":
115
+ demo.queue().launch()