muhammadsalmanalfaridzi commited on
Commit
f8387c1
Β·
verified Β·
1 Parent(s): a152d82

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +157 -0
app.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from cerebras.cloud.sdk import Cerebras
3
+ from markdown import markdown
4
+ from weasyprint import HTML
5
+ import gradio as gr
6
+
7
+ # Ensure you get the API key from environment variables
8
+ api_key = os.environ.get("CEREBRAS_API_KEY")
9
+
10
+ # Functions for resume optimization
11
+ def create_prompt(resume_string: str, jd_string: str) -> str:
12
+ """
13
+ Creates a detailed prompt for AI-powered resume optimization based on a job description.
14
+ """
15
+ return f"""
16
+ You are a professional resume optimization expert specializing in tailoring resumes to specific job descriptions. Your goal is to optimize my resume and provide actionable suggestions for improvement to align with the target role.
17
+
18
+ ### Guidelines:
19
+ 1. **Relevance**:
20
+ - Prioritize experiences, skills, and achievements **most relevant to the job description**.
21
+ - Remove or de-emphasize irrelevant details to ensure a **concise** and **targeted** resume.
22
+ - Limit work experience section to 2-3 most relevant roles
23
+ - Limit bullet points under each role to 2-3 most relevant impacts
24
+
25
+ 2. **Action-Driven Results**:
26
+ - Use **strong action verbs** and **quantifiable results** (e.g., percentages, revenue, efficiency improvements) to highlight impact.
27
+
28
+ 3. **Keyword Optimization**:
29
+ - Integrate **keywords** and phrases from the job description naturally to optimize for ATS (Applicant Tracking Systems).
30
+
31
+ 4. **Additional Suggestions** *(If Gaps Exist)*:
32
+ - If the resume does not fully align with the job description, suggest:
33
+ 1. **Additional technical or soft skills** that I could add to make my profile stronger.
34
+ 2. **Certifications or courses** I could pursue to bridge the gap.
35
+ 3. **Project ideas or experiences** that would better align with the role.
36
+
37
+ 5. **Formatting**:
38
+ - Output the tailored resume in **clean Markdown format**.
39
+ - Include an **"Additional Suggestions"** section at the end with actionable improvement recommendations.
40
+
41
+ ---
42
+
43
+ ### Input:
44
+ - **My resume**:
45
+ {resume_string}
46
+
47
+ - **The job description**:
48
+ {jd_string}
49
+
50
+ ---
51
+
52
+ ### Output:
53
+ 1. **Tailored Resume**:
54
+ - A resume in **Markdown format** that emphasizes relevant experience, skills, and achievements.
55
+ - Incorporates job description **keywords** to optimize for ATS.
56
+ - Uses strong language and is no longer than **one page**.
57
+
58
+ 2. **Additional Suggestions** *(if applicable)*:
59
+ - List **skills** that could strengthen alignment with the role.
60
+ - Recommend **certifications or courses** to pursue.
61
+ - Suggest **specific projects or experiences** to develop.
62
+ """
63
+
64
+ def get_resume_response(prompt: str, api_key: str, model: str = "llama-3.3-70b", temperature: float = 0.7) -> str:
65
+ """
66
+ Sends a resume optimization prompt to Cerebras' API and returns the optimized resume response.
67
+ """
68
+ # Initialize the Cerebras client with the API key
69
+ client = Cerebras(api_key=api_key)
70
+
71
+ # Make API call using the Llama 3.3 70B model
72
+ stream = client.chat.completions.create(
73
+ messages=[
74
+ {"role": "system", "content": "Expert resume writer"},
75
+ {"role": "user", "content": prompt}
76
+ ],
77
+ model=model,
78
+ stream=True,
79
+ temperature=temperature,
80
+ max_completion_tokens=1024,
81
+ top_p=1
82
+ )
83
+
84
+ # Collect the response chunks from the stream
85
+ response_string = ""
86
+ for chunk in stream:
87
+ response_string += chunk.choices[0].delta.content or ""
88
+
89
+ return response_string
90
+
91
+ def process_resume(resume, jd_string):
92
+ """
93
+ Process a resume file against a job description to create an optimized version.
94
+ """
95
+ # Read the resume
96
+ with open(resume, "r", encoding="utf-8") as file:
97
+ resume_string = file.read()
98
+
99
+ # Create prompt for optimization
100
+ prompt = create_prompt(resume_string, jd_string)
101
+
102
+ # Generate the optimized resume using Cerebras' Llama 3.3 70B model
103
+ response_string = get_resume_response(prompt, api_key)
104
+ response_list = response_string.split("## Additional Suggestions")
105
+
106
+ # Extract new resume and suggestions for improvement
107
+ new_resume = response_list[0]
108
+ suggestions = "## Additional Suggestions \n\n" + response_list[1]
109
+
110
+ return new_resume, new_resume, suggestions
111
+
112
+ def export_resume(new_resume):
113
+ """
114
+ Convert a markdown resume to PDF format and save it.
115
+ """
116
+ try:
117
+ # Save as PDF
118
+ output_pdf_file = "resumes/resume_new.pdf"
119
+
120
+ # Convert Markdown to HTML
121
+ html_content = markdown(new_resume)
122
+
123
+ # Convert HTML to PDF and save
124
+ HTML(string=html_content).write_pdf(output_pdf_file, stylesheets=['resumes/style.css'])
125
+
126
+ return f"Successfully exported resume to {output_pdf_file} πŸŽ‰"
127
+ except Exception as e:
128
+ return f"Failed to export resume: {str(e)} πŸ’”"
129
+
130
+ # Hugging Face Space UI
131
+ with gr.Blocks() as app:
132
+ # Create header and app description
133
+ gr.Markdown("# Resume Optimizer πŸ“„")
134
+ gr.Markdown("Upload your resume, paste the job description, and get actionable insights!")
135
+
136
+ # Gather inputs
137
+ with gr.Row():
138
+ resume_input = gr.File(label="Upload Your Resume (.md)")
139
+ jd_input = gr.Textbox(label="Paste the Job Description Here", lines=9, interactive=True, placeholder="Paste job description...")
140
+
141
+ run_button = gr.Button("Optimize Resume πŸ€–")
142
+
143
+ # Display outputs
144
+ output_resume_md = gr.Markdown(label="New Resume")
145
+ output_suggestions = gr.Markdown(label="Suggestions")
146
+
147
+ # Editing results
148
+ output_resume = gr.Textbox(label="Edit resume and export!", interactive=True)
149
+ export_button = gr.Button("Export Resume as PDF πŸš€")
150
+ export_result = gr.Markdown(label="Export Result")
151
+
152
+ # Event binding
153
+ run_button.click(process_resume, inputs=[resume_input, jd_input], outputs=[output_resume_md, output_resume, output_suggestions])
154
+ export_button.click(export_resume, inputs=[output_resume], outputs=[export_result])
155
+
156
+ # Launch the app
157
+ app.launch()