Spaces:
Sleeping
Sleeping
| 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") | |
| 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], | |
| ) | |
| 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], | |
| ) | |
| 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() | |