Afeezee commited on
Commit
f54dc6b
·
verified ·
1 Parent(s): 841d08b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +163 -0
app.py ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ from pdfminer.high_level import extract_text
4
+ from docx import Document
5
+ from groq import Groq
6
+
7
+ key = os.getenv("GroqCVs")
8
+ client = Groq(api_key=key)
9
+
10
+ # Function to read PDF files
11
+ def read_pdf(file_path):
12
+ return extract_text(file_path)
13
+
14
+ # Function to read DOCX files
15
+ def read_docx(file_path):
16
+ doc = Document(file_path)
17
+ return "\n".join([paragraph.text for paragraph in doc.paragraphs])
18
+
19
+ # Function to optimize CV using Llama 3.1 and Groq API
20
+ def optimize_cv_with_llama(cv_text, job_description):
21
+ try:
22
+ # Compose the prompt
23
+ system_message = (
24
+ "You are an experienced Human Resource expert with 30 years of experience working for major international companies. "
25
+ "Your task is to optimize the following CV or Resume based on the provided job description. Tailor the CV content to align "
26
+ "with the job requirements and highlight relevant skills, experiences, and achievements. Present the optimized CV in Markdown format. "
27
+ "Ensure the formatting is professional and avoid adding extra comments."
28
+ )
29
+
30
+ # Send the job description and CV text to the Groq API
31
+ completion = client.chat.completions.create(
32
+ model="llama-3.3-70b-versatile",
33
+ messages=[
34
+ {"role": "system", "content": system_message},
35
+ {"role": "user", "content": f"Job Description:\n{job_description}\n\nCV:\n{cv_text}"}
36
+ ],
37
+ temperature=0.7,
38
+ max_tokens=2048,
39
+ top_p=0.9,
40
+ stream=False,
41
+ )
42
+
43
+ # Return the optimized Markdown text
44
+ return ''.join([chunk.message.content for chunk in completion.choices])
45
+ except Exception as e:
46
+ return f"Error optimizing CV: {e}"
47
+
48
+ # Function to save optimized Markdown as DOCX
49
+ from markdown2 import markdown
50
+ from bs4 import BeautifulSoup
51
+
52
+ def save_markdown_to_docx(markdown_text, output_docx_path="optimized_cv.docx"):
53
+ # Convert Markdown to HTML
54
+ html_content = markdown(markdown_text)
55
+
56
+ # Parse HTML with BeautifulSoup
57
+ soup = BeautifulSoup(html_content, "html.parser")
58
+
59
+ # Create a new DOCX document
60
+ doc = Document()
61
+
62
+ # Iterate through HTML elements and map them to DOCX formatting
63
+ for element in soup.descendants:
64
+ if element.name == "h1":
65
+ para = doc.add_paragraph(element.text, style="Heading 1")
66
+ elif element.name == "h2":
67
+ para = doc.add_paragraph(element.text, style="Heading 2")
68
+ elif element.name == "h3":
69
+ para = doc.add_paragraph(element.text, style="Heading 3")
70
+ elif element.name == "ul": # Unordered list
71
+ for li in element.find_all("li"):
72
+ doc.add_paragraph(li.text, style="List Bullet")
73
+ elif element.name == "ol": # Ordered list
74
+ for li in element.find_all("li"):
75
+ doc.add_paragraph(li.text, style="List Number")
76
+ elif element.name == "p": # Paragraph
77
+ doc.add_paragraph(element.text)
78
+ elif element.name == "strong": # Bold text
79
+ para = doc.add_paragraph()
80
+ run = para.add_run(element.text)
81
+ run.bold = True
82
+ elif element.name == "em": # Italics
83
+ para = doc.add_paragraph()
84
+ run = para.add_run(element.text)
85
+ run.italic = True
86
+ elif element.name == "a": # Hyperlink
87
+ para = doc.add_paragraph(element.text) # Add the text of the hyperlink
88
+ # Add the URL as well, optionally
89
+ para.add_run(f" ({element.get('href')})").italic = True
90
+
91
+ # Save the document
92
+ doc.save(output_docx_path)
93
+ return output_docx_path
94
+
95
+ # Function to process file upload and optimization
96
+ def process_inputs(cv_file, job_description):
97
+ try:
98
+ # Extract text from uploaded file
99
+ file_path = cv_file.name
100
+ file_extension = os.path.splitext(file_path)[1].lower()
101
+ if file_extension == ".pdf":
102
+ cv_text = read_pdf(file_path)
103
+ elif file_extension == ".docx":
104
+ cv_text = read_docx(file_path)
105
+ else:
106
+ return "Unsupported file format", None
107
+
108
+ # Optimize the CV based on the job description
109
+ optimized_markdown = optimize_cv_with_llama(cv_text, job_description)
110
+
111
+ # Save the optimized Markdown as DOCX
112
+ output_docx_path = "optimized_cv.docx"
113
+ save_markdown_to_docx(optimized_markdown, output_docx_path)
114
+
115
+ return optimized_markdown, output_docx_path
116
+ except Exception as e:
117
+ return f"Error processing inputs: {e}", None
118
+
119
+ # Gradio Interface
120
+ def main():
121
+ with gr.Blocks() as app:
122
+ # Title and Description
123
+ gr.Markdown(
124
+ """
125
+ # **AI-Powered CV Optimizer**
126
+ Optimize your CV or Resume to match job descriptions using the power of AI.
127
+ This application processes your uploaded CV along with a job description and generates a tailored, professional CV ready for submission.
128
+ """
129
+ )
130
+
131
+ # Input components
132
+ file_input = gr.File(label="Upload Your CV (PDF or DOCX)")
133
+
134
+
135
+ job_description = gr.Textbox(
136
+ label="Job Description",
137
+ placeholder="Paste the job description here...",
138
+ lines=5
139
+ )
140
+
141
+
142
+ # Output components
143
+ markdown_output = gr.Markdown(label="Optimized CV Preview")
144
+ download_button = gr.File(label="Download Optimized CV (DOCX)")
145
+
146
+ # Button to process inputs
147
+ run_button = gr.Button("Optimize CV")
148
+
149
+ # Define the interaction logic
150
+ def handle_inputs(cv_file, job_description):
151
+ markdown_text, docx_path = process_inputs(cv_file, job_description)
152
+ return markdown_text, docx_path
153
+
154
+ run_button.click(
155
+ handle_inputs,
156
+ inputs=[file_input, job_description],
157
+ outputs=[markdown_output, download_button]
158
+ )
159
+
160
+ app.launch(debug=True)
161
+
162
+ if __name__ == "__main__":
163
+ main()