Spaces:
Running
Running
Delete services/dashboard_sync_handlers.py
Browse files
services/dashboard_sync_handlers.py
DELETED
|
@@ -1,147 +0,0 @@
|
|
| 1 |
-
# handlers/dashboard_sync_handlers.py
|
| 2 |
-
import gradio as gr
|
| 3 |
-
import logging
|
| 4 |
-
|
| 5 |
-
# Assuming these functions are in the specified paths and are importable
|
| 6 |
-
from services.state_manager import process_and_store_bubble_token
|
| 7 |
-
from services.sync_logic import sync_all_linkedin_data_orchestrator
|
| 8 |
-
from ui.ui_generators import display_main_dashboard
|
| 9 |
-
|
| 10 |
-
class DashboardSyncHandlers:
|
| 11 |
-
def __init__(self, dashboard_components, token_state_ref, url_user_token_display_ref, org_urn_display_ref, status_box_ref):
|
| 12 |
-
self.components = dashboard_components
|
| 13 |
-
self.token_state = token_state_ref # gr.State object
|
| 14 |
-
self.url_user_token_display = url_user_token_display_ref # gr.Textbox object
|
| 15 |
-
self.org_urn_display = org_urn_display_ref # gr.Textbox object
|
| 16 |
-
self.status_box = status_box_ref # gr.Textbox object
|
| 17 |
-
|
| 18 |
-
logging.info("DashboardSyncHandlers initialized.")
|
| 19 |
-
|
| 20 |
-
def initial_load_sequence(self, url_token, org_urn_val, current_token_state_value):
|
| 21 |
-
"""
|
| 22 |
-
Handles the initial loading sequence after URL parameters are fetched.
|
| 23 |
-
This is called by app.load().then() or org_urn_display.change().
|
| 24 |
-
"""
|
| 25 |
-
logging.info(f"Initial load sequence triggered. URL Token: {'Set' if url_token else 'Not Set'}, Org URN: {org_urn_val}")
|
| 26 |
-
|
| 27 |
-
# process_and_store_bubble_token is expected to return:
|
| 28 |
-
# status_msg, new_state_dict, btn_update_dict (for sync_data_btn)
|
| 29 |
-
status_msg, new_state_dict, btn_update_dict = process_and_store_bubble_token(
|
| 30 |
-
url_token,
|
| 31 |
-
org_urn_val,
|
| 32 |
-
current_token_state_value # Pass the current value of the state
|
| 33 |
-
)
|
| 34 |
-
|
| 35 |
-
# display_main_dashboard expects the new state dictionary
|
| 36 |
-
dashboard_content_html = display_main_dashboard(new_state_dict)
|
| 37 |
-
|
| 38 |
-
# Returns:
|
| 39 |
-
# 1. Update for status_box (value)
|
| 40 |
-
# 2. New value for token_state (this will update the gr.State object)
|
| 41 |
-
# 3. Update for sync_data_btn (e.g., gr.update(visible=True, interactive=True))
|
| 42 |
-
# 4. Update for dashboard_display_html (value)
|
| 43 |
-
return status_msg, new_state_dict, btn_update_dict, dashboard_content_html
|
| 44 |
-
|
| 45 |
-
async def trigger_sync_and_refresh(self, current_token_state_value, url_token, org_urn_val):
|
| 46 |
-
"""
|
| 47 |
-
Orchestrates the full sync process when the sync button is clicked.
|
| 48 |
-
This combines sync_all_linkedin_data_orchestrator and subsequent updates.
|
| 49 |
-
Yields updates for a chained sequence.
|
| 50 |
-
"""
|
| 51 |
-
logging.info("Sync data button clicked. Starting sync process.")
|
| 52 |
-
|
| 53 |
-
# Part 1: sync_all_linkedin_data_orchestrator
|
| 54 |
-
# Expected to return: html_status_update_str, updated_token_state_dict
|
| 55 |
-
sync_status_html, updated_token_state_after_sync = await sync_all_linkedin_data_orchestrator(current_token_state_value)
|
| 56 |
-
yield sync_status_html, updated_token_state_after_sync # Updates sync_status_html_output, token_state
|
| 57 |
-
|
| 58 |
-
# Part 2: process_and_store_bubble_token again with potentially updated token_state
|
| 59 |
-
# This ensures the state is consistent after sync and reflects any new data fetched by sync_all_linkedin_data_orchestrator
|
| 60 |
-
# It might also re-evaluate if sync button should be visible/interactive
|
| 61 |
-
status_msg_after_sync, final_token_state_dict, sync_btn_update_after_sync = process_and_store_bubble_token(
|
| 62 |
-
url_token, # url_token and org_urn_val might be stale if not re-fetched, but usually static for a session
|
| 63 |
-
org_urn_val,
|
| 64 |
-
updated_token_state_after_sync # Use the state updated by sync_all_linkedin_data_orchestrator
|
| 65 |
-
)
|
| 66 |
-
yield status_msg_after_sync, final_token_state_dict, sync_btn_update_after_sync # Updates status_box, token_state, sync_data_btn
|
| 67 |
-
|
| 68 |
-
# Part 3: Refresh dashboard display
|
| 69 |
-
dashboard_html_after_sync = display_main_dashboard(final_token_state_dict)
|
| 70 |
-
yield dashboard_html_after_sync # Updates dashboard_display_html
|
| 71 |
-
|
| 72 |
-
# The subsequent calls to refresh_analytics_graphs_ui and run_agentic_pipeline_autonomously
|
| 73 |
-
# will be chained in app.py using .then() on this sync event, using the updated token_state.
|
| 74 |
-
|
| 75 |
-
def setup_event_handlers(self, initial_load_trigger_component, agentic_handlers_ref, analytics_handlers_ref):
|
| 76 |
-
"""
|
| 77 |
-
Sets up event handlers for the dashboard and sync tab.
|
| 78 |
-
initial_load_trigger_component is typically org_urn_display.
|
| 79 |
-
"""
|
| 80 |
-
logging.info("Setting up dashboard/sync event handlers.")
|
| 81 |
-
|
| 82 |
-
# Initial load sequence
|
| 83 |
-
# This is more complex due to the chained .then() calls for analytics and agentic pipeline
|
| 84 |
-
# The main app.py will handle the .then() chaining. This handler provides the core functions.
|
| 85 |
-
# The initial_load_sequence method itself will be the 'fn' for the first .change() or .load().
|
| 86 |
-
|
| 87 |
-
# Sync button click
|
| 88 |
-
# The sync_data_btn.click event will also have .then() chains in app.py
|
| 89 |
-
# We define the primary function here.
|
| 90 |
-
self.components['sync_data_btn'].click(
|
| 91 |
-
fn=self.trigger_sync_and_refresh,
|
| 92 |
-
inputs=[
|
| 93 |
-
self.token_state,
|
| 94 |
-
self.url_user_token_display, # Pass the component to get its current value
|
| 95 |
-
self.org_urn_display # Pass the component to get its current value
|
| 96 |
-
],
|
| 97 |
-
outputs=[
|
| 98 |
-
self.components['sync_status_html_output'], # Output 1 from sync_all_linkedin_data
|
| 99 |
-
self.token_state, # Output 2 from sync_all_linkedin_data
|
| 100 |
-
self.status_box, # Output 1 from process_and_store (after sync)
|
| 101 |
-
self.token_state, # Output 2 from process_and_store (after sync)
|
| 102 |
-
self.components['sync_data_btn'], # Output 3 from process_and_store (after sync)
|
| 103 |
-
self.components['dashboard_display_html'] # Output from display_main_dashboard (after sync)
|
| 104 |
-
],
|
| 105 |
-
show_progress="full",
|
| 106 |
-
api_name="sync_linkedin_data_full_flow"
|
| 107 |
-
# Note: The number of outputs here must match the total number of yields in trigger_sync_and_refresh
|
| 108 |
-
# trigger_sync_and_refresh yields:
|
| 109 |
-
# 1. sync_status_html (for sync_status_html_output)
|
| 110 |
-
# 2. updated_token_state_after_sync (for token_state)
|
| 111 |
-
# --- then ---
|
| 112 |
-
# 3. status_msg_after_sync (for status_box)
|
| 113 |
-
# 4. final_token_state_dict (for token_state)
|
| 114 |
-
# 5. sync_btn_update_after_sync (for sync_data_btn)
|
| 115 |
-
# --- then ---
|
| 116 |
-
# 6. dashboard_html_after_sync (for dashboard_display_html)
|
| 117 |
-
# This means the Gradio event needs to be structured to handle these yields if they are separate updates.
|
| 118 |
-
# However, Gradio's .click typically expects a single function that returns all outputs or a generator
|
| 119 |
-
# that yields tuples of updates for all outputs at each step.
|
| 120 |
-
# For simplicity, trigger_sync_and_refresh should be an async generator yielding tuples for all outputs.
|
| 121 |
-
# Let's refine trigger_sync_and_refresh to yield tuples.
|
| 122 |
-
)
|
| 123 |
-
logging.info("Dashboard/sync event handlers setup complete.")
|
| 124 |
-
|
| 125 |
-
async def refined_trigger_sync_and_refresh(self, current_token_state_value, url_token, org_urn_val):
|
| 126 |
-
"""
|
| 127 |
-
Refined orchestrator for sync process, yielding tuples for all outputs at each step.
|
| 128 |
-
Outputs:
|
| 129 |
-
1. self.components['sync_status_html_output']
|
| 130 |
-
2. self.token_state
|
| 131 |
-
3. self.status_box
|
| 132 |
-
4. self.components['sync_data_btn'] (this is tricky, might need to be separate or handled by token_state change)
|
| 133 |
-
5. self.components['dashboard_display_html']
|
| 134 |
-
|
| 135 |
-
Let's simplify the outputs for the direct click and handle subsequent updates via .then() in app.py
|
| 136 |
-
The click will call sync_all_linkedin_data_orchestrator.
|
| 137 |
-
Then, .then() will call process_and_store_bubble_token.
|
| 138 |
-
Then, .then() will call display_main_dashboard.
|
| 139 |
-
And further .then() for agentic and analytics.
|
| 140 |
-
So, this handler will provide the individual functions.
|
| 141 |
-
"""
|
| 142 |
-
pass # The original structure in app.py with chained .then() is better.
|
| 143 |
-
# This class will hold the functions called by those .then() chains.
|
| 144 |
-
# sync_all_linkedin_data_orchestrator
|
| 145 |
-
# process_and_store_bubble_token (already imported)
|
| 146 |
-
# display_main_dashboard (already imported)
|
| 147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|