ps1811 commited on
Commit
bc99da9
Β·
verified Β·
1 Parent(s): aab34cc

Updated app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -68
app.py CHANGED
@@ -1,95 +1,95 @@
1
- # STEP 1: MUST BE THE FIRST MACHINE LEARNING IMPORT
2
- import spaces
3
  import gradio as gr
4
- import pandas as pd
5
  import os
6
-
7
  from app.db.repo import init_db
8
- from app.ui.dashboard import load_dashboard, build_dashboard
 
9
  from app.controller.session_loader import load_google_ads_data
10
-
11
  from app.ads1.ads_analyst import run_ads_analyst_card
12
  from app.ads1.budget_optimizer import run_budget_optimizer_card
13
 
14
- init_db()
 
 
 
 
 
15
 
16
- # HELPERS
17
- def on_campaign_select(campaign_name):
 
 
 
18
  dfs = load_google_ads_data()
19
- filtered = dfs.copy()
20
- filtered["campaigns"] = dfs["campaigns"][
21
- dfs["campaigns"]["name"] == campaign_name
22
- ]
23
- return filtered
24
 
25
- # STEP 2: DECORATE THE GPU-INTENSIVE FUNCTIONS
26
- @spaces.GPU()
27
  def run_ads_card(state):
28
  if not state:
29
- return "⚠️ Please select a campaign from the Dashboard first."
30
- return run_ads_analyst_card(state["dfs"])
31
 
32
- @spaces.GPU()
33
  def run_budget_card(state):
34
  if not state:
35
- return "⚠️ Please select a campaign from the Dashboard first."
36
- return run_budget_optimizer_card(state["dfs"])
37
 
38
- def campaign_row_selected(evt: gr.SelectData):
39
- """
40
- Triggered when user clicks a row in the dashboard table
41
- """
42
- df = load_dashboard()[4] # campaign table returned by load_dashboard()
43
- campaign_name = df.iloc[evt.index[0]]["Campaign"]
44
- dfs = on_campaign_select(campaign_name)
45
 
46
- return (
47
- {
48
- "campaign_name": campaign_name,
49
- "dfs": dfs
50
- },
51
- f"## πŸ“Š Selected Campaign: {campaign_name}"
52
- )
53
-
54
- # GRADIO APP
55
- with gr.Blocks(title="Ads Assistant") as demo:
56
  campaign_state = gr.State()
57
- gr.Markdown("# 🎯 Preschool Ads Dashboard")
58
 
59
- # TAB 1: DASHBOARD
60
- with gr.Tab("Dashboard"):
61
- campaign_table = build_dashboard()
62
 
63
- # TAB 2: CAMPAIGN ANALYSIS
64
- with gr.Tab("Campaign Analysis"):
65
- selected_campaign = gr.Markdown(
66
- "πŸ‘ˆ Select a campaign from the Dashboard tab"
67
- )
68
- analyst_btn = gr.Button("Run Ads Analysis")
69
- budget_btn = gr.Button("Run Budget Optimization")
70
- output = gr.Markdown()
71
 
72
- analyst_btn.click(
73
- fn=run_ads_card,
74
- inputs=campaign_state,
75
- outputs=output
76
- )
77
 
78
- budget_btn.click(
79
- fn=run_budget_card,
80
- inputs=campaign_state,
81
- outputs=output
82
- )
 
 
83
 
84
- # CONNECT TABLE CLICK β†’ STATE
 
 
85
  campaign_table.select(
86
  fn=campaign_row_selected,
87
- outputs=[
88
- campaign_state,
89
- selected_campaign
90
- ]
 
 
 
 
 
 
 
 
 
 
91
  )
92
 
93
- # STEP 3: CLEAN LAUNCH FOR HUGGING FACE
94
- # Do not specify server_name or server_port; HF manages this automatically.
95
- demo.launch()
 
 
 
1
  import gradio as gr
 
2
  import os
 
3
  from app.db.repo import init_db
4
+ from app.ui.dashboard import build_dashboard, get_dashboard_data
5
+ from app.controller.campaign_controller import on_campaign_select
6
  from app.controller.session_loader import load_google_ads_data
 
7
  from app.ads1.ads_analyst import run_ads_analyst_card
8
  from app.ads1.budget_optimizer import run_budget_optimizer_card
9
 
10
+ def startup():
11
+ try:
12
+ init_db()
13
+ print("βœ… DB initialized successfully")
14
+ except Exception as e:
15
+ print("⚠️ DB init failed:", e)
16
 
17
+ startup()
18
+
19
+ # UI Optimization: Fetch data AFTER UI elements are drawn
20
+ def initial_data_load():
21
+ print("πŸ”„ App loaded. Population of background states initiated...")
22
  dfs = load_google_ads_data()
23
+ # Unpack dashboard metrics to fill the UI immediately
24
+ spend, leads, cpl, count, formatted_df = get_dashboard_data()
25
+ return dfs, formatted_df, spend, leads, cpl, count
 
 
26
 
 
 
27
  def run_ads_card(state):
28
  if not state:
29
+ return "⚠️ Select a campaign from the Dashboard tab first."
30
+ return run_ads_analyst_card(state["full_dfs"])
31
 
 
32
  def run_budget_card(state):
33
  if not state:
34
+ return "⚠️ Select a campaign from the Dashboard tab first."
35
+ return run_budget_optimizer_card(state["full_dfs"])
36
 
37
+ def campaign_row_selected(evt: gr.SelectData, df, full_state):
38
+ if df.empty or full_state is None:
39
+ return gr.State(), "⚠️ Data state is missing. Please click Refresh."
40
+ row_index = evt.index[0]
41
+ campaign_name = df.iloc[row_index]["Campaign"]
42
+ campaign_state = on_campaign_select(full_state, campaign_name)
43
+ return campaign_state, f"## πŸ“Š Selected Campaign: {campaign_name}"
44
 
45
+ with gr.Blocks() as demo:
46
+ # Initialize components empty; populated safely via demo.load
47
+ full_state = gr.State()
 
 
 
 
 
 
 
48
  campaign_state = gr.State()
49
+ df_state = gr.State()
50
 
51
+ gr.Markdown("# 🎯 Ads Dashboard")
 
 
52
 
53
+ with gr.Tab("Dashboard"):
54
+ # We modify build_dashboard to expose metric components for automated hydration
55
+ gr.Markdown("## πŸ“Š Campaign Dashboard")
56
+ with gr.Row():
57
+ total_spend = gr.Number(label="Total Spend")
58
+ total_leads = gr.Number(label="Total Leads")
59
+ average_cpl = gr.Number(label="Average CPL")
60
+ active_campaigns = gr.Number(label="Active Campaigns")
61
 
62
+ campaign_table = gr.Dataframe(label="Campaign Performance", interactive=True)
63
+ refresh_btn = gr.Button("πŸ”„ Force Refresh Data")
 
 
 
64
 
65
+ with gr.Tab("Analysis"):
66
+ selected = gr.Markdown("πŸ‘ˆ Select a campaign from the Dashboard tab")
67
+ output = gr.Markdown()
68
+
69
+ with gr.Row():
70
+ gr.Button("πŸš€ Run Ads Analysis").click(run_ads_card, campaign_state, output)
71
+ gr.Button("πŸ’° Run Budget Optimization").click(run_budget_card, campaign_state, output)
72
 
73
+ # Core Event Bindings
74
+ campaign_table.change(fn=lambda x: x, inputs=[campaign_table], outputs=df_state)
75
+
76
  campaign_table.select(
77
  fn=campaign_row_selected,
78
+ inputs=[df_state, full_state],
79
+ outputs=[campaign_state, selected]
80
+ )
81
+
82
+ # Button manual refresh
83
+ refresh_btn.click(
84
+ fn=initial_data_load,
85
+ outputs=[full_state, campaign_table, total_spend, total_leads, average_cpl, active_campaigns]
86
+ )
87
+
88
+ # ⚑ MAGIC FIX: App automatically loads data into UI components instantly on launch
89
+ demo.load(
90
+ fn=initial_data_load,
91
+ outputs=[full_state, campaign_table, total_spend, total_leads, average_cpl, active_campaigns]
92
  )
93
 
94
+ if __name__ == "__main__":
95
+ demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860)))