GuglielmoTor commited on
Commit
c61d44a
Β·
verified Β·
1 Parent(s): fc169c4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +12 -32
app.py CHANGED
@@ -45,10 +45,8 @@ def guarded_fetch_analytics(token_state):
45
  """Guarded call to fetch_and_render_analytics, ensuring token and basic data structures."""
46
  if not token_state or not token_state.get("token"):
47
  logging.warning("Analytics fetch: Access denied. No token.")
48
- # Ensure the number of returned Nones matches the expected number of outputs for the plots
49
  return ("❌ Access denied. No token.", None, None, None, None, None, None, None)
50
 
51
- # Ensure DataFrames are passed, even if empty, to avoid errors in the analytics function
52
  posts_df_analytics = token_state.get("bubble_posts_df", pd.DataFrame())
53
  mentions_df_analytics = token_state.get("bubble_mentions_df", pd.DataFrame())
54
  follower_stats_df_analytics = token_state.get("bubble_follower_stats_df", pd.DataFrame())
@@ -72,34 +70,28 @@ def guarded_fetch_analytics(token_state):
72
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
73
  title="LinkedIn Organization Dashboard") as app:
74
 
75
- # Central state for holding token, client_id, org_urn, and fetched dataframes
76
  token_state = gr.State(value={
77
  "token": None, "client_id": None, "org_urn": None,
78
  "bubble_posts_df": pd.DataFrame(), "fetch_count_for_api": 0,
79
  "bubble_mentions_df": pd.DataFrame(),
80
  "bubble_follower_stats_df": pd.DataFrame(),
81
- "bubble_operations_log_df": pd.DataFrame(), # Added from your state_manager logic
82
- "mentions_should_sync_now": False, # Added from your state_manager logic
83
- "fs_should_sync_now": False, # Added from your state_manager logic
84
  "url_user_token_temp_storage": None
85
  })
86
 
87
  gr.Markdown("# πŸš€ LinkedIn Organization Dashboard")
88
- # Hidden textboxes to capture URL parameters
89
  url_user_token_display = gr.Textbox(label="User Token (from URL - Hidden)", interactive=False, visible=False)
90
  status_box = gr.Textbox(label="Overall LinkedIn Token Status", interactive=False, value="Initializing...")
91
  org_urn_display = gr.Textbox(label="Organization URN (from URL - Hidden)", interactive=False, visible=False)
92
 
93
- # Load URL parameters when the Gradio app loads
94
  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)
95
 
96
- # This function will run after URL params are loaded and org_urn_display changes
97
  def initial_load_sequence(url_token, org_urn_val, current_state):
98
  logging.info(f"Initial load sequence triggered. Org URN: {org_urn_val}, URL Token: {'Present' if url_token else 'Absent'}")
99
- # Process token, fetch Bubble data, determine sync needs
100
  status_msg, new_state, btn_update = process_and_store_bubble_token(url_token, org_urn_val, current_state)
101
- # Display initial dashboard content based on (potentially empty) Bubble data
102
- dashboard_content = display_main_dashboard(new_state) # Ensure this function handles potentially empty dfs
103
  return status_msg, new_state, btn_update, dashboard_content
104
 
105
  with gr.Tabs():
@@ -107,43 +99,35 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
107
  gr.Markdown("System checks for existing data from Bubble. The 'Sync' button activates if new data needs to be fetched from LinkedIn based on the last sync times and data availability.")
108
  sync_data_btn = gr.Button("πŸ”„ Sync LinkedIn Data", variant="primary", visible=False, interactive=False)
109
 
110
- # This HTML component will now display the animation during sync
111
- sync_status_html_output = gr.HTML("<p style='text-align:center;'>Sync status will appear here.</p>")
112
 
113
  dashboard_display_html = gr.HTML("<p style='text-align:center;'>Dashboard loading...</p>")
114
 
115
- # Chain of events for initial load:
116
  org_urn_display.change(
117
  fn=initial_load_sequence,
118
  inputs=[url_user_token_display, org_urn_display, token_state],
119
  outputs=[status_box, token_state, sync_data_btn, dashboard_display_html],
120
  show_progress="full"
121
  )
122
- # Note: The logic for also triggering on url_user_token_display.change has been removed
123
- # as org_urn_display.change should be sufficient if get_url_user_token updates both,
124
- # or if org_urn is the primary trigger. If issues arise, this can be revisited.
125
 
126
- # When Sync button is clicked:
127
  sync_data_btn.click(
128
- fn=lambda: get_sync_animation_html(), # Step 1: Show animation
129
  inputs=None,
130
  outputs=[sync_status_html_output],
131
- show_progress=False # Animation is its own progress indicator
132
  ).then(
133
- fn=sync_all_linkedin_data_orchestrator, # Step 2: Run the actual sync
134
  inputs=[token_state],
135
- # sync_all_linkedin_data_orchestrator must return:
136
- # 1. HTML string for status (replaces animation)
137
- # 2. Updated token_state
138
  outputs=[sync_status_html_output, token_state],
139
- show_progress=False # Rely on animation; or set to "full" if you want Gradio's default too
140
  ).then(
141
- fn=process_and_store_bubble_token, # Step 3: Re-check sync status and update button
142
  inputs=[url_user_token_display, org_urn_display, token_state],
143
  outputs=[status_box, token_state, sync_data_btn],
144
  show_progress=False
145
  ).then(
146
- fn=display_main_dashboard, # Step 4: Refresh dashboard display
147
  inputs=[token_state],
148
  outputs=[dashboard_display_html],
149
  show_progress=False
@@ -191,7 +175,6 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
191
  )
192
 
193
  if __name__ == "__main__":
194
- # Check for essential environment variables
195
  if not os.environ.get(LINKEDIN_CLIENT_ID_ENV_VAR):
196
  logging.warning(f"WARNING: '{LINKEDIN_CLIENT_ID_ENV_VAR}' environment variable not set. The app may not function correctly for LinkedIn API calls.")
197
  if not os.environ.get(BUBBLE_APP_NAME_ENV_VAR) or \
@@ -202,10 +185,7 @@ if __name__ == "__main__":
202
  try:
203
  import matplotlib
204
  logging.info(f"Matplotlib version: {matplotlib.__version__} found. Backend: {matplotlib.get_backend()}")
205
- # The backend is now set in ui_generators.py, which is good practice.
206
  except ImportError:
207
  logging.error("Matplotlib is not installed. Plots will not be generated. Please install it: pip install matplotlib")
208
 
209
- # Launch the Gradio app
210
- # Ensure share=False for local testing unless you intend to share it via Gradio's link
211
  app.launch(server_name="0.0.0.0", server_port=7860, debug=True, share=False)
 
45
  """Guarded call to fetch_and_render_analytics, ensuring token and basic data structures."""
46
  if not token_state or not token_state.get("token"):
47
  logging.warning("Analytics fetch: Access denied. No token.")
 
48
  return ("❌ Access denied. No token.", None, None, None, None, None, None, None)
49
 
 
50
  posts_df_analytics = token_state.get("bubble_posts_df", pd.DataFrame())
51
  mentions_df_analytics = token_state.get("bubble_mentions_df", pd.DataFrame())
52
  follower_stats_df_analytics = token_state.get("bubble_follower_stats_df", pd.DataFrame())
 
70
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"),
71
  title="LinkedIn Organization Dashboard") as app:
72
 
 
73
  token_state = gr.State(value={
74
  "token": None, "client_id": None, "org_urn": None,
75
  "bubble_posts_df": pd.DataFrame(), "fetch_count_for_api": 0,
76
  "bubble_mentions_df": pd.DataFrame(),
77
  "bubble_follower_stats_df": pd.DataFrame(),
78
+ "bubble_operations_log_df": pd.DataFrame(),
79
+ "mentions_should_sync_now": False,
80
+ "fs_should_sync_now": False,
81
  "url_user_token_temp_storage": None
82
  })
83
 
84
  gr.Markdown("# πŸš€ LinkedIn Organization Dashboard")
 
85
  url_user_token_display = gr.Textbox(label="User Token (from URL - Hidden)", interactive=False, visible=False)
86
  status_box = gr.Textbox(label="Overall LinkedIn Token Status", interactive=False, value="Initializing...")
87
  org_urn_display = gr.Textbox(label="Organization URN (from URL - Hidden)", interactive=False, visible=False)
88
 
 
89
  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)
90
 
 
91
  def initial_load_sequence(url_token, org_urn_val, current_state):
92
  logging.info(f"Initial load sequence triggered. Org URN: {org_urn_val}, URL Token: {'Present' if url_token else 'Absent'}")
 
93
  status_msg, new_state, btn_update = process_and_store_bubble_token(url_token, org_urn_val, current_state)
94
+ dashboard_content = display_main_dashboard(new_state)
 
95
  return status_msg, new_state, btn_update, dashboard_content
96
 
97
  with gr.Tabs():
 
99
  gr.Markdown("System checks for existing data from Bubble. The 'Sync' button activates if new data needs to be fetched from LinkedIn based on the last sync times and data availability.")
100
  sync_data_btn = gr.Button("πŸ”„ Sync LinkedIn Data", variant="primary", visible=False, interactive=False)
101
 
102
+ # MODIFIED: Added height=400 (or adjust as needed)
103
+ sync_status_html_output = gr.HTML("<p style='text-align:center;'>Sync status will appear here.</p>", height=400)
104
 
105
  dashboard_display_html = gr.HTML("<p style='text-align:center;'>Dashboard loading...</p>")
106
 
 
107
  org_urn_display.change(
108
  fn=initial_load_sequence,
109
  inputs=[url_user_token_display, org_urn_display, token_state],
110
  outputs=[status_box, token_state, sync_data_btn, dashboard_display_html],
111
  show_progress="full"
112
  )
 
 
 
113
 
 
114
  sync_data_btn.click(
115
+ fn=lambda: get_sync_animation_html(),
116
  inputs=None,
117
  outputs=[sync_status_html_output],
118
+ show_progress=False
119
  ).then(
120
+ fn=sync_all_linkedin_data_orchestrator,
121
  inputs=[token_state],
 
 
 
122
  outputs=[sync_status_html_output, token_state],
123
+ show_progress=False
124
  ).then(
125
+ fn=process_and_store_bubble_token,
126
  inputs=[url_user_token_display, org_urn_display, token_state],
127
  outputs=[status_box, token_state, sync_data_btn],
128
  show_progress=False
129
  ).then(
130
+ fn=display_main_dashboard,
131
  inputs=[token_state],
132
  outputs=[dashboard_display_html],
133
  show_progress=False
 
175
  )
176
 
177
  if __name__ == "__main__":
 
178
  if not os.environ.get(LINKEDIN_CLIENT_ID_ENV_VAR):
179
  logging.warning(f"WARNING: '{LINKEDIN_CLIENT_ID_ENV_VAR}' environment variable not set. The app may not function correctly for LinkedIn API calls.")
180
  if not os.environ.get(BUBBLE_APP_NAME_ENV_VAR) or \
 
185
  try:
186
  import matplotlib
187
  logging.info(f"Matplotlib version: {matplotlib.__version__} found. Backend: {matplotlib.get_backend()}")
 
188
  except ImportError:
189
  logging.error("Matplotlib is not installed. Plots will not be generated. Please install it: pip install matplotlib")
190
 
 
 
191
  app.launch(server_name="0.0.0.0", server_port=7860, debug=True, share=False)