hola-ivan commited on
Commit
01b2099
Β·
verified Β·
1 Parent(s): 688190f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -29
app.py CHANGED
@@ -71,13 +71,21 @@ def adapt_resume(resume_data, keywords, job_description, model, max_retries=3):
71
 
72
  for attempt in range(max_retries):
73
  try:
74
- prompt = f"""You are a CV coach skilled in resume customization and JSON formatting. Consider what the ideal candidate for the target role would be like. You have creative freedom to tailor the provided base Original CV JSON to align with the company's needs using relevant keywords based on their importance level (high: 3x, medium: 2x, low: 1x). Use the language established in the Keywords. IMPORTANT: Consider the company's research and job details to enhance the CV's relevance.
75
- Embed relevant keywords throughout specific sections: 'summary', 'experience', 'volunteer', 'interests', 'awards', 'projects' and 'skills' without altering any factual information.
76
- Output the modified CV as JSON, strictly maintaining the original structure, keys, and logical flow of information. Use the language specified in the Keywords and avoid adding any fabricated details.
77
- Retain specific keys such as 'id' and 'url' as in the original CV, as well as any key found within the 'metadata' section of the schema.
78
- Schema: {json.dumps(original_schema)}
 
 
 
 
 
 
 
 
79
  Keywords: {json.dumps(keywords)}
80
- Job: {job_description}"""
81
 
82
  response = model.generate_content(prompt)
83
  tailored_resume = json.loads(response.text)
@@ -123,16 +131,76 @@ def calculate_resume_match(resume_data, keywords):
123
 
124
  return normalized_score, matches
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  # Page config
127
  st.set_page_config(page_title="Resume Tailor", page_icon="πŸ“„", layout="wide")
128
 
129
  # Header
130
- st.title("🎯 AI Resume Tailor")
131
  st.markdown("### Transform your resume for your dream job")
132
  # Sidebar with API key
133
  with st.sidebar:
134
- st.markdown("### Google API Key")
135
  st.markdown("This tool works with Google's Gemini model, which you can use for free. For more information, visit [Google AI Studio](https://ai.google.dev/aistudio).")
 
 
 
 
 
 
 
 
 
 
136
  api_key = st.secrets["google_api_key"]
137
  if not api_key:
138
  st.error("API key not found in secrets. Please add your API key to the secrets.")
@@ -148,7 +216,7 @@ with col2:
148
  st.session_state['original_resume'] = json.load(resume_str)
149
 
150
  # Process button
151
- if st.button("πŸš€ Tailor Resume", type="primary", use_container_width=True):
152
  if job_url and api_key and resume_file:
153
  try:
154
  with st.status("πŸ”„ Processing...") as status:
@@ -173,7 +241,7 @@ if st.button("πŸš€ Tailor Resume", type="primary", use_container_width=True):
173
 
174
  # Results section
175
  st.markdown("---")
176
- st.markdown("### πŸ“Š Results")
177
 
178
  # Calculate and display scores
179
  original_score, original_matches = calculate_resume_match(
@@ -185,24 +253,13 @@ if st.button("πŸš€ Tailor Resume", type="primary", use_container_width=True):
185
  st.session_state['keywords']
186
  )
187
 
188
- score_col1, score_col2 = st.columns(2)
189
- with score_col1:
190
- st.metric("Original Match", f"{original_score:.1f}%")
191
- with score_col2:
192
- st.metric("Tailored Match", f"{tailored_score:.1f}%",
193
- delta=f"+{tailored_score - original_score:.1f}%")
194
-
195
- # Keyword matches
196
- with st.expander("🎯 View Keyword Matches"):
197
- for priority in ['high', 'medium', 'low']:
198
- st.subheader(f"{priority.title()} Priority")
199
- orig_matches = set(original_matches[priority])
200
- new_matches = set(tailored_matches[priority])
201
- added = new_matches - orig_matches
202
-
203
- st.write("βœ“ Original:", ", ".join(orig_matches) if orig_matches else "None")
204
- if added:
205
- st.write("✚ Added:", f"<span style='background-color: #d4edda;'>{', '.join(added)}</span>", unsafe_allow_html=True)
206
 
207
  # Download section
208
  st.markdown("### πŸ“₯ Download")
@@ -214,7 +271,7 @@ if st.button("πŸš€ Tailor Resume", type="primary", use_container_width=True):
214
  use_container_width=True
215
  ):
216
  webbrowser.open_new_tab("https://rxresu.me/")
217
- st.info("πŸ“ Opening Resume Builder in new tab...")
218
 
219
  except Exception as e:
220
  st.error(f"An error occurred: {str(e)}")
 
71
 
72
  for attempt in range(max_retries):
73
  try:
74
+ prompt = f"""As a CV expert, optimize the provided resume JSON for the target role.
75
+ Enhance sections (summary, experience, volunteer, interests, awards, projects, skills) by incorporating provided keywords:
76
+ - High priority (3x weight)
77
+ - Medium priority (2x weight)
78
+ - Low priority (1x weight)
79
+
80
+ Rules:
81
+ - Keep all original facts and information
82
+ - Maintain exact JSON structure and all existing keys
83
+ - Use natural language from the keywords list
84
+ - Do not add fictional content
85
+
86
+ Base Schema: {json.dumps(original_schema)}
87
  Keywords: {json.dumps(keywords)}
88
+ Job Description: {job_description}"""
89
 
90
  response = model.generate_content(prompt)
91
  tailored_resume = json.loads(response.text)
 
131
 
132
  return normalized_score, matches
133
 
134
+ def create_match_visualization(original_score, tailored_score, keywords, original_matches, tailored_matches):
135
+ """Create visualization showing resume match comparison"""
136
+
137
+ # Overall score comparison
138
+ st.markdown("### πŸ“Š Resume Match Analysis")
139
+
140
+ # Score metrics side by side
141
+ col1, col2 = st.columns(2)
142
+ with col1:
143
+ st.metric(
144
+ "Original Resume Match Score",
145
+ f"{original_score:.1f}%"
146
+ )
147
+ with col2:
148
+ st.metric(
149
+ "Tailored Resume Match Score",
150
+ f"{tailored_score:.1f}%",
151
+ delta=f"+{tailored_score - original_score:.1f}%"
152
+ )
153
+
154
+ # Keyword analysis by priority
155
+ st.markdown("### 🎯 Keyword Matches")
156
+ tabs = st.tabs(["High Priority πŸ”΄", "Medium Priority 🟑", "Low Priority 🟒"])
157
+
158
+ for idx, priority in enumerate(['high', 'medium', 'low']):
159
+ with tabs[idx]:
160
+ col1, col2 = st.columns(2)
161
+
162
+ orig_matches = set(original_matches[priority])
163
+ new_matches = set(tailored_matches[priority])
164
+ added = new_matches - orig_matches
165
+
166
+ # Original matches
167
+ with col1:
168
+ st.markdown("#### Original Matching Keywords")
169
+ if orig_matches:
170
+ for keyword in orig_matches:
171
+ st.markdown(f"βœ“ `{keyword}`")
172
+ else:
173
+ st.info("No matches found")
174
+
175
+ # New matches
176
+ with col2:
177
+ st.markdown("#### Added the following Keywords")
178
+ if added:
179
+ for keyword in added:
180
+ st.markdown(f"βž• `{keyword}`")
181
+ else:
182
+ st.info("No new matches")
183
+
184
  # Page config
185
  st.set_page_config(page_title="Resume Tailor", page_icon="πŸ“„", layout="wide")
186
 
187
  # Header
188
+ st.title("πŸ“„ Curriculum Customization Tool")
189
  st.markdown("### Transform your resume for your dream job")
190
  # Sidebar with API key
191
  with st.sidebar:
192
+ st.markdown("### About")
193
  st.markdown("This tool works with Google's Gemini model, which you can use for free. For more information, visit [Google AI Studio](https://ai.google.dev/aistudio).")
194
+
195
+ # Disclaimer
196
+ st.warning("""
197
+ ⚠️ **Disclaimer**
198
+
199
+ This tool is for educational purposes only.
200
+ AI-based tools can produce unexpected or inaccurate results.
201
+ By using this tool, you accept full responsibility for verifying and using its output.
202
+ """)
203
+
204
  api_key = st.secrets["google_api_key"]
205
  if not api_key:
206
  st.error("API key not found in secrets. Please add your API key to the secrets.")
 
216
  st.session_state['original_resume'] = json.load(resume_str)
217
 
218
  # Process button
219
+ if st.button("🎯 Tailor Resume", type="primary", use_container_width=True):
220
  if job_url and api_key and resume_file:
221
  try:
222
  with st.status("πŸ”„ Processing...") as status:
 
241
 
242
  # Results section
243
  st.markdown("---")
244
+ st.markdown("## πŸ“Š Results")
245
 
246
  # Calculate and display scores
247
  original_score, original_matches = calculate_resume_match(
 
253
  st.session_state['keywords']
254
  )
255
 
256
+ create_match_visualization(
257
+ original_score,
258
+ tailored_score,
259
+ st.session_state['keywords'],
260
+ original_matches,
261
+ tailored_matches
262
+ )
 
 
 
 
 
 
 
 
 
 
 
263
 
264
  # Download section
265
  st.markdown("### πŸ“₯ Download")
 
271
  use_container_width=True
272
  ):
273
  webbrowser.open_new_tab("https://rxresu.me/")
274
+ st.info("πŸ“ Resume Builder opened in new tab")
275
 
276
  except Exception as e:
277
  st.error(f"An error occurred: {str(e)}")