Spaces:
Sleeping
Sleeping
File size: 17,857 Bytes
4246a25 89d54b1 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 89d54b1 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 4246a25 b3cbb46 89d54b1 4246a25 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 |
import os
import gradio as gr
from dotenv import load_dotenv
from app.constants import ROLE_PLACEHOLDER, SAMPLE_RESULT
from app.utils import copy_to_clipboard, export_state
from linkedinadvice.career_analysis import CareerAnalyzer
from linkedinadvice.monitoring import monitor_api
# Load environment variables
load_dotenv()
# Check if API key is set
if not os.getenv("OPENAI_API_KEY"):
raise ValueError("OPENAI_API_KEY not found in environment variables")
# Initialize career analyzer
analyzer = CareerAnalyzer(model_name="gpt-4o-mini")
@monitor_api
def analyze_career(
*args,
):
result = analyzer.analyze(*args)
return result
# Building the interface
with gr.Blocks(theme="soft") as demo:
# State for number of roles
role_count = gr.State(1) # Start with 1 role field
education_count = gr.State(1) # Start with 1 education field
professional_background_dict = gr.State({}) # State to store combined roles data
education_background_dict = gr.State({}) # State to store combined education data
professional_background = gr.State("") # State to store combined roles data
professional_achievements = gr.State("") # State to store combined roles data
education_background = gr.State("") # State to store combined education background
education_achievements = gr.State("") # State to store education achievements
goals = gr.State("") # State to store combined goals
insights = gr.State("") # State to store combined insights
time_preference = gr.State("Mid-term (10 years)") # State to store time preference
financial_weight = gr.State(2) # State to store financial weight
impact_weight = gr.State(2) # State to store impact weight
opportunity_weight = gr.State(2) # State to store opportunity weight
output = gr.State("") # State to store output
raw_list_inputs = gr.State([]) # State to store raw list inputs
gr.Markdown(
"""
# Career Pathway Analysis
This tool analyzes your professional background and provides tailored career path recommendations.
It evaluates options based on financial potential, human impact, and opportunity creation.
"""
)
with gr.Row():
submit_btn = gr.Button("Analyze Career Paths", variant="primary", size="lg")
clear_btn = gr.Button("Clear", variant="stop", size="lg")
example_btn = gr.Button("Load Example", variant="secondary", size="lg")
with gr.Row():
with gr.Column(scale=3):
with gr.Group():
gr.Markdown("### Professional Information")
gr.Markdown("*Add your current and previous professional roles*")
with gr.Row():
add_role_btn = gr.Button(
"β Add", variant="secondary", size="sm", key="add_role_btn"
)
remove_role_btn = gr.Button(
"β Remove",
variant="secondary",
size="sm",
key="remove_role_btn",
)
add_role_btn.click(
lambda x: x + 1,
inputs=[role_count],
outputs=[role_count],
)
remove_role_btn.click(
lambda x: max(x - 1, 1),
inputs=[role_count],
outputs=[role_count],
)
@gr.render(inputs=role_count)
def render_roles(r_count):
for i in range(r_count):
if i not in professional_background_dict.value:
professional_background_dict.value[i] = {
"role": "",
"exp": "",
"professional_achievement": "",
}
with gr.Row():
interactive = i == r_count - 1
role = gr.Textbox(
key=f"role_{i}",
label=f"Role {i + 1}"
+ (" (Current)" if i == 0 else ""),
placeholder=ROLE_PLACEHOLDER[i % len(ROLE_PLACEHOLDER)],
scale=3,
interactive=interactive,
inputs=professional_background_dict.value[i].get(
"role", ""
),
)
def update_professional_background_dict(key, value, i):
professional_background_dict.value[i][key] = value
final_string = ""
for i in professional_background_dict.value:
role = professional_background_dict.value[i].get(
"role"
)
exp = professional_background_dict.value[i].get(
"exp"
)
professional_achievement = (
professional_background_dict.value[i].get(
"professional_achievement"
)
)
final_string += f"{role} - {exp} years. Achieved: \n{professional_achievement}\n\n"
return professional_background_dict.value, final_string
role.input(
lambda x: update_professional_background_dict(
"role", x, i
),
inputs=[role],
outputs=[
professional_background_dict,
professional_background,
],
)
exp = gr.Number(
key=f"exp_{i}",
label="Years",
value=1,
minimum=0,
scale=1,
interactive=interactive,
)
exp.input(
lambda x: update_professional_background_dict(
"exp", x, i
),
inputs=[exp],
outputs=[
professional_background_dict,
professional_background,
],
)
professional_achievement = gr.Textbox(
key=f"professional_achievement_{i}",
label="Notable Achievements",
lines=2,
placeholder="List key accomplishments, awards, or significant contributions.",
interactive=interactive,
)
professional_achievement.input(
lambda x: update_professional_background_dict(
"professional_achievement", x, i
),
inputs=[professional_achievement],
outputs=[
professional_background_dict,
professional_background,
],
)
raw_list_inputs.value.extend(
[role, exp, professional_achievement]
)
with gr.Group():
gr.Markdown("### Educational Background")
gr.Markdown("*Add your current and previous academic experiences*")
with gr.Row():
add_education_btn = gr.Button(
"β Add",
variant="secondary",
size="sm",
key="add_education_btn",
)
remove_education_btn = gr.Button(
"β Remove",
variant="secondary",
size="sm",
key="remove_education_btn",
)
add_education_btn.click(
lambda x: x + 1,
inputs=[education_count],
outputs=[education_count],
)
remove_education_btn.click(
lambda x: max(x - 1, 1),
inputs=[education_count],
outputs=[education_count],
)
@gr.render(inputs=education_count)
def render_education(e_count):
for i in range(e_count):
if i not in education_background_dict.value:
education_background_dict.value[i] = {
"education": "",
"education_achievement": "",
}
with gr.Row():
education = gr.Textbox(
key=f"education_{i}",
label="Academic Experience",
lines=3,
placeholder="e.g. Bachelor of Science in Computer Science, University of Technology",
)
def update_educational_background_dict(key, value, i):
education_background_dict.value[i][key] = value
final_string = ""
for i in education_background_dict.value:
education = education_background_dict.value[i].get(
"education"
)
edu_achievement = education_background_dict.value[
i
].get("edu_achievement")
final_string += f"{education}. Achieved: \n{edu_achievement}\n\n"
return education_background_dict.value, final_string
education.input(
lambda x: update_educational_background_dict(
"education", x, i
),
inputs=[education],
outputs=[
education_background_dict,
education_background,
],
)
edu_achievement = gr.Textbox(
key=f"edu_achievement_{i}",
label="Academic Achievements",
lines=3,
placeholder="Awards, honors, notable projects or research during your education",
)
edu_achievement.input(
lambda x: update_educational_background_dict(
"education_achievement", x, i
),
inputs=[education_achievements],
outputs=[
education_background_dict,
education_background,
],
)
if education.value:
education_background.value += education.value
if edu_achievement.value:
education_achievements.value += edu_achievement.value
raw_list_inputs.value.extend([education, edu_achievement])
with gr.Group():
gr.Markdown("### Future Plans")
goals = gr.Textbox(
label="Career Goals",
lines=3,
placeholder="Describe your short-term and long-term career objectives",
key="goals",
)
insights = gr.Textbox(
label="Additional Insights",
lines=3,
placeholder="Other relevant information like skills, interests, or constraints",
key="insights",
)
with gr.Group():
gr.Markdown("### Analysis Preferences")
gr.Markdown(
"*Adjust the importance of each factor in career evaluation*"
)
time_preference = gr.Radio(
[
"Short-term (3 years)",
"Mid-term (10 years)",
"Long-term (10+ years)",
],
label="Time Horizon Preference",
value="Mid-term (10 years)",
key="time_preference",
)
with gr.Row():
with gr.Column(scale=1):
financial_weight = gr.Radio(
[1, 2, 3],
value=2,
label="π° Financial Potential",
info="Earning potential and financial growth",
elem_classes=["weight-radio"],
key="financial_weight",
)
with gr.Column(scale=1):
impact_weight = gr.Radio(
[1, 2, 3],
value=2,
label="π« Human Impact",
info="Positive impact on others and society",
elem_classes=["weight-radio"],
key="impact_weight",
)
with gr.Column(scale=1):
opportunity_weight = gr.Radio(
[1, 2, 3],
value=2,
label="πͺ Opportunity Creation",
info="Doors opened for future growth and options",
elem_classes=["weight-radio"],
key="opportunity_weight",
)
with gr.Column(scale=2):
output_box = gr.Markdown(
output.value,
container=True,
height=614,
show_copy_button=True,
key="output_box",
)
with gr.Row():
copy_btn = gr.Button("π Copy to Clipboard", variant="secondary")
share_btn = gr.Button("π Share on LinkedIn", variant="secondary")
# Copy and share functionality
copy_btn.click(
copy_to_clipboard,
inputs=output_box,
)
# Add info section at the bottom
with gr.Accordion("About This Tool", open=False):
gr.Markdown(
"""
This career analysis tool uses AI to generate personalized career path recommendations
based on your professional background, education, and goals.
**How It Works:**
1. Enter your current and previous roles with years of experience
2. Provide information about your achievements and education
3. Set your preferences for analysis (time horizon and factor weights)
4. Get a detailed analysis of potential career paths with scoring
The analysis evaluates each career path on three dimensions:
- **Financial Potential**: Earning capacity and financial growth
- **Human Impact**: Contribution to society and positive influence
- **Opportunity Creation**: Future opportunities and career flexibility
You can adjust the weights to prioritize what matters most to you.
"""
)
submit_btn.click(
lambda *args: analyze_career(*args) if export_state(*args) or True else None,
inputs=[
professional_background,
education_background,
goals,
insights,
time_preference,
financial_weight,
impact_weight,
opportunity_weight,
],
outputs=[output_box],
)
clear_btn.click(
fn=lambda: None, inputs=[], outputs=[], js="() => location.reload()"
)
example_btn.click(
fn=lambda _: SAMPLE_RESULT,
inputs=[output_box],
outputs=[output_box],
)
# Launch the app
if __name__ == "__main__":
demo.launch()
|