Spaces:
Running
Running
File size: 10,618 Bytes
b560569 575b933 b0464a9 87a87e7 21988b0 791c130 8add36b f7fc39b 575b933 826a2a1 2e2e19a 8add36b 575b933 21988b0 2e2e19a 945226d 9aa3bfe 945226d 21988b0 dd307a7 8add36b 21988b0 dd307a7 21988b0 8add36b bde3d91 21988b0 2601f1c dd307a7 bb1bc48 dd307a7 21988b0 5a483f8 21988b0 8add36b ddc6277 21988b0 ddc6277 bde3d91 ddc6277 8add36b 21988b0 8add36b ddc6277 21988b0 bde3d91 4699b09 bde3d91 4699b09 bde3d91 dd307a7 8853c45 4699b09 ddc6277 6b39ad4 5cc5759 4699b09 77179e2 8add36b dd307a7 9aa3bfe dd307a7 9aa3bfe dd307a7 8add36b bde3d91 dd307a7 1644cc1 2e2e19a dd307a7 9aa3bfe dd307a7 9aa3bfe dd307a7 3c8e890 dd307a7 3c8e890 dd307a7 00de3b2 adb3bbe dd307a7 8add36b dd307a7 21988b0 dd307a7 |
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 |
import gradio as gr
import pandas as pd
import os
import logging
from collections import defaultdict
import matplotlib
matplotlib.use('Agg') # Set backend for Matplotlib
# --- Module Imports ---
from utils.gradio_utils import get_url_user_token
# Functions from newly created/refactored modules
from config import (
PLOT_ID_TO_FORMULA_KEY_MAP,
LINKEDIN_CLIENT_ID_ENV_VAR,
BUBBLE_APP_NAME_ENV_VAR,
BUBBLE_API_KEY_PRIVATE_ENV_VAR,
BUBBLE_API_ENDPOINT_ENV_VAR
)
# analytics_tab_module is now imported locally inside ui/ui_enhancements.py's build_main_app_ui
# from services.analytics_tab_module import AnalyticsTab # REMOVED global import here
# UPDATED: Using the new data loading function from the refactored state manager
from services.state_manager import load_data_from_bubble
# Import UI generator functions (these are now passed to build_main_app_ui)
from ui.ui_generators import (
build_analytics_tab_plot_area,
build_home_tab_ui,
create_enhanced_report_tab,
BOMB_ICON, EXPLORE_ICON, FORMULA_ICON, ACTIVE_ICON
)
# NEW: Import the new OKR UI functions
from ui.okr_ui_generator import create_enhanced_okr_tab, format_okrs_for_enhanced_display, get_initial_okr_display
from ui.analytics_plot_generator import update_analytics_plots_figures, create_placeholder_plot
from formulas import PLOT_FORMULAS
# NEW: Import UI enhancements from the new module
from ui.ui_main_page_enhancements import build_main_app_ui, update_report_display_enhanced
# --- CHATBOT MODULE IMPORTS ---
from features.chatbot.chatbot_prompts import get_initial_insight_prompt_and_suggestions
from features.chatbot.chatbot_handler import generate_llm_response
# --- AGENTIC PIPELINE (DISPLAY ONLY) IMPORTS ---
try:
# This is the main function called on initial load to populate the agentic tabs
from run_agentic_pipeline import load_and_display_agentic_results
# This function is now called when a new report is selected from the dropdown
from services.report_data_handler import fetch_and_reconstruct_data_from_bubble
# UI formatting functions
from ui.insights_ui_generator import (
format_report_for_display, # This will now return header HTML and body Markdown
)
AGENTIC_MODULES_LOADED = True
except ImportError as e:
logging.error(f"Could not import agentic pipeline display modules: {e}. Tabs 3 and 4 will be disabled.")
AGENTIC_MODULES_LOADED = False
# Placeholder functions to prevent app from crashing if imports fail
def load_and_display_agentic_results(*args, **kwargs):
# NOTE: This return signature MUST match agentic_display_outputs
# Adjusted return values for the new split report display components and the new OKR HTML
empty_header_html = """
<div class="report-title">π Comprehensive Analysis Report</div>
<div class="report-subtitle">AI-Generated Insights from Your LinkedIn Data</div>
<div class="status-badge">Generated from Bubble.io</div>
"""
empty_body_markdown = """
<div class="empty-state">
<div class="empty-state-icon">π</div>
<div class="empty-state-title">No Report Selected</div>
<div class="empty-state-description">
Please select a report from the library above to view its detailed analysis and insights.
</div>
</div>
"""
# The load_and_display_agentic_results function returns many values.
# Ensure the placeholder returns the correct number of gr.update components
# matching the `outputs` in the .then() call later.
return (
gr.update(value="Modules not loaded."), # agentic_pipeline_status_md (0)
gr.update(choices=[], value=None), # report_selector_dd (1)
gr.update(choices=[], value=[]), # key_results_cbg (2) - KEPT HIDDEN for compatibility
gr.update(value="Modules not loaded."), # okr_detail_display_md (3) - KEPT HIDDEN for compatibility
None, # orchestration_raw_results_st (4)
[], # selected_key_result_ids_st (5) - KEPT HIDDEN for compatibility
[], # key_results_for_selection_st (6) - KEPT HIDDEN for compatibility
gr.update(value=empty_header_html), # report_header_html_display (7)
gr.update(value=empty_body_markdown), # report_body_markdown_display (8)
{}, # reconstruction_cache_st (9)
gr.update(value=get_initial_okr_display()), # NEW: enhanced_okr_display_html (10)
gr.update(value={}) # NEW: actionable_okrs_data_st (11)
)
def fetch_and_reconstruct_data_from_bubble(*args, **kwargs):
return None, {}
def format_report_for_display(report_data):
# Placeholder for when modules are not loaded, returns structure matching the new design
return {'header_html': '<h1>Agentic modules not loaded.</h1>', 'body_markdown': 'Report display unavailable.'}
# --- Initial data load sequence function (remains in app.py as it uses service functions) ---
def initial_data_load_sequence(url_token, org_urn_val, current_state):
"""
Handles the initial data loading from Bubble.
No longer generates dashboard HTML as the Home tab is now static.
"""
status_msg, new_state = load_data_from_bubble(url_token, org_urn_val, current_state)
# Add status icons based on success/failure
if "successfully" in status_msg.lower() or "loaded" in status_msg.lower():
status_msg = f"β
{status_msg}"
elif "error" in status_msg.lower() or "failed" in status_msg.lower():
status_msg = f"β {status_msg}"
else:
status_msg = f"π {status_msg}"
return status_msg, new_state
# Build the main UI using the function from ui_enhancements
(app, url_user_token_display, org_urn_display, status_box,
token_state, reconstruction_cache_st, enhanced_okr_display_html,
tabs, report_selector_dd, agentic_display_outputs,
analytics_tab_instance, chat_histories_st_returned,
current_chat_plot_id_st_returned, plot_data_for_chatbot_st_returned, # Receive these returned states
format_report_for_display_func_passed) = \
build_main_app_ui(
PLOT_ID_TO_FORMULA_KEY_MAP=PLOT_ID_TO_FORMULA_KEY_MAP,
PLOT_FORMULAS=PLOT_FORMULAS,
BOMB_ICON=BOMB_ICON, EXPLORE_ICON=EXPLORE_ICON, FORMULA_ICON=FORMULA_ICON, ACTIVE_ICON=ACTIVE_ICON,
build_analytics_tab_plot_area_func=build_analytics_tab_plot_area,
update_analytics_plots_figures_func=update_analytics_plots_figures,
create_placeholder_plot_func=create_placeholder_plot,
get_initial_insight_prompt_and_suggestions_func=get_initial_insight_prompt_and_suggestions,
generate_llm_response_func=generate_llm_response,
build_home_tab_ui_func=build_home_tab_ui,
create_enhanced_report_tab_func=create_enhanced_report_tab,
create_enhanced_okr_tab_func=create_enhanced_okr_tab,
format_report_for_display_func=format_report_for_display # Pass the imported function
)
# Event handlers (re-establishing them now that components are defined)
app.load(fn=get_url_user_token, inputs=None, outputs=[url_user_token_display, org_urn_display], api_name="get_url_params", show_progress=False)
if AGENTIC_MODULES_LOADED:
report_selector_dd.change(
fn=lambda sr_id, c_state: update_report_display_enhanced(sr_id, c_state, format_report_for_display),
inputs=[report_selector_dd, token_state],
outputs=[agentic_display_outputs[7], agentic_display_outputs[8]], # report_header_html_display, report_body_markdown_display
show_progress="minimal"
)
# Initial load sequence with enhanced status updates
initial_load_event = org_urn_display.change(
fn=initial_data_load_sequence,
inputs=[url_user_token_display, org_urn_display, token_state],
outputs=[status_box, token_state],
show_progress="full"
)
# Chain the loading events
initial_load_event.then(
fn=analytics_tab_instance.refresh_analytics_graphs_ui,
inputs=[token_state, analytics_tab_instance.date_filter_selector, analytics_tab_instance.custom_start_date_picker,
analytics_tab_instance.custom_end_date_picker, chat_histories_st_returned],
outputs=analytics_tab_instance.graph_refresh_outputs_list,
show_progress="full"
).then(
fn=load_and_display_agentic_results,
inputs=[token_state, reconstruction_cache_st],
outputs=agentic_display_outputs,
show_progress="minimal"
).then(
fn=format_okrs_for_enhanced_display,
inputs=[reconstruction_cache_st],
outputs=[enhanced_okr_display_html],
show_progress="minimal"
)
if __name__ == "__main__":
# Enhanced startup logging
print("π Starting LinkedIn Organization Dashboard...")
# Environment variable checks with better logging
missing_vars = []
if not os.environ.get(LINKEDIN_CLIENT_ID_ENV_VAR):
missing_vars.append(LINKEDIN_CLIENT_ID_ENV_VAR)
logging.warning(f"β οΈ WARNING: '{LINKEDIN_CLIENT_ID_ENV_VAR}' is not set.")
bubble_vars = [BUBBLE_APP_NAME_ENV_VAR, BUBBLE_API_KEY_PRIVATE_ENV_VAR, BUBBLE_API_ENDPOINT_ENV_VAR]
if not all(os.environ.get(var) for var in bubble_vars):
missing_vars.extend([var for var in bubble_vars if not os.environ.get(var)])
logging.warning("β οΈ WARNING: One or more Bubble environment variables are not set.")
if not os.environ.get("GEMINI_API_KEY"):
missing_vars.append("GEMINI_API_KEY")
logging.warning("β οΈ WARNING: 'GEMINI_API_KEY' is not set.")
if not AGENTIC_MODULES_LOADED:
logging.warning("π΄ CRITICAL: Agentic modules failed to load.")
if missing_vars:
print(f"β οΈ Missing environment variables: {', '.join(missing_vars)}")
print("π§ Please set these variables for full functionality.")
else:
print("β
All environment variables are properly configured.")
print("π Launching dashboard on http://0.0.0.0:7860")
print("π― Dashboard features:")
print(" β’ π Advanced LinkedIn Analytics")
print(" β’ π€ AI-Powered Insights")
print(" β’ π― OKR Generation & Tracking")
print(" β’ βοΈ Bubble.io Integration")
app.launch(
server_name="0.0.0.0",
server_port=int(os.environ.get("PORT", 7860)),
debug=True,
show_error=True,
show_tips=True,
enable_queue=True
)
|