codewithRiz commited on
Commit
d0aaafd
Β·
1 Parent(s): 8320dd2
Files changed (1) hide show
  1. app.py +52 -98
app.py CHANGED
@@ -1,23 +1,29 @@
1
  import gradio as gr
2
- from huggingface_hub import list_bucket_tree, download_bucket_files
3
- from datetime import datetime
4
  import pandas as pd
5
  import json
6
  import os
 
7
  from dotenv import load_dotenv
8
 
9
- # ---------- LOAD ENV ----------
10
  load_dotenv()
11
  BUCKET_NAME = os.getenv("BUCKET_NAME")
 
 
 
12
 
13
  PAGE_SIZE = 5
14
-
15
-
16
- # ---------- LOAD DATA FROM BUCKET ----------
17
  def extract_customer_data():
18
  try:
19
- tree = list_bucket_tree(BUCKET_NAME, recursive=True)
20
-
 
 
 
 
 
 
 
21
  json_files = [
22
  item.path for item in tree
23
  if item.path.endswith("cameras.json")
@@ -25,153 +31,101 @@ def extract_customer_data():
25
 
26
  if not json_files:
27
  return pd.DataFrame(columns=["customer_id", "customer_name", "customer_email"])
28
-
29
- files_map = [(f, f"C:/tmp/{f.replace('/', '_')}") for f in json_files]
30
-
31
- download_bucket_files(BUCKET_NAME, files=files_map)
32
-
 
 
 
 
 
33
  rows = []
34
-
35
  for remote_path, local_path in files_map:
36
  parts = remote_path.split("/")
37
  customer_id = parts[1] if len(parts) > 1 else "unknown"
38
-
39
  try:
40
  with open(local_path, "r", encoding="utf-8") as f:
41
  data = json.load(f)
42
-
43
  for item in data:
44
  rows.append({
45
  "customer_id": customer_id,
46
  "customer_name": item.get("customer_name"),
47
  "customer_email": item.get("customer_email")
48
  })
49
-
50
  except Exception as e:
51
  print(f"File error {remote_path}: {e}")
52
-
53
  df = pd.DataFrame(rows)
54
-
55
- # ---------- REMOVE DUPLICATES ----------
56
  if not df.empty:
57
- df = df.drop_duplicates(
58
- subset=["customer_id", "customer_name", "customer_email"]
59
- )
60
-
61
  return df
62
-
63
  except Exception as e:
64
- print("ERROR:", e)
65
  return pd.DataFrame(columns=["customer_id", "customer_name", "customer_email"])
66
-
67
-
68
- # ---------- FILTER ----------
69
- def apply_search(df, email_query):
70
- if df is None or not isinstance(df, pd.DataFrame):
71
  return pd.DataFrame(columns=["customer_id", "customer_name", "customer_email"])
72
-
 
 
 
73
  if email_query:
74
  df = df[df["customer_email"].astype(str).str.contains(email_query, case=False, na=False)]
75
-
76
  return df
77
-
78
-
79
- # ---------- PAGINATION ----------
80
  def build_view(df, page, email_query):
81
  filtered = apply_search(df, email_query)
82
-
83
  total_pages = max(1, (len(filtered) - 1) // PAGE_SIZE + 1)
84
  page = max(0, min(page, total_pages - 1))
85
-
86
  start = page * PAGE_SIZE
87
  end = start + PAGE_SIZE
88
-
89
  paged = filtered.iloc[start:end]
90
-
91
- status = f"Page {page+1} / {total_pages} | Total Results: {len(filtered)}"
92
-
93
  return paged, page, status
94
-
95
-
96
- # ---------- ACTIONS ----------
97
- def search(df, email_query):
98
- page = 0
99
- table, page, status = build_view(df, page, email_query)
100
- return table, page, status, df
101
-
102
-
103
- def next_page(df, page, email_query):
104
- page = page + 1
105
- table, page, status = build_view(df, page, email_query)
106
- return table, page, status, df
107
-
108
-
109
- def prev_page(df, page, email_query):
110
- page = page - 1
111
- table, page, status = build_view(df, page, email_query)
112
- return table, page, status, df
113
-
114
-
115
- def refresh_data(email_query):
116
- df = extract_customer_data()
117
- page = 0
118
- table, page, status = build_view(df, page, email_query)
119
- return table, page, status, df
120
-
121
-
122
- # ---------- INITIAL DATA ----------
123
- df_global = extract_customer_data()
124
-
125
-
126
- # ---------- UI ----------
127
  with gr.Blocks() as app:
128
  gr.Markdown("# πŸ›° Buck Tracker Customer Dashboard")
129
-
130
  state_df = gr.State(df_global)
131
  state_page = gr.State(0)
132
-
133
- search_box = gr.Textbox(
134
- label="πŸ” Search Customer Email",
135
- placeholder="Enter email to search..."
136
- )
137
-
138
  table = gr.Dataframe(
139
  value=build_view(df_global, 0, "")[0],
140
- interactive=False,
141
- label="Customer Data"
142
  )
143
-
144
  status = gr.Textbox(interactive=False)
145
-
146
  with gr.Row():
147
- refresh_btn = gr.Button("πŸ”„ Refresh Bucket Data", variant="primary")
148
- prev_btn = gr.Button("⬅️ Previous")
149
- next_btn = gr.Button("Next ➑️")
150
-
151
- # ---------- EVENTS ----------
152
-
 
 
 
 
 
153
  search_box.change(
154
- fn=search,
155
  inputs=[state_df, search_box],
156
  outputs=[table, state_page, status, state_df]
157
  )
158
-
159
  refresh_btn.click(
160
- fn=refresh_data,
161
  inputs=[search_box],
162
  outputs=[table, state_page, status, state_df]
163
  )
164
-
165
  next_btn.click(
166
  fn=next_page,
167
  inputs=[state_df, state_page, search_box],
168
  outputs=[table, state_page, status, state_df]
169
  )
170
-
171
  prev_btn.click(
172
  fn=prev_page,
173
  inputs=[state_df, state_page, search_box],
174
  outputs=[table, state_page, status, state_df]
175
  )
176
-
177
  app.launch()
 
1
  import gradio as gr
2
+ from huggingface_hub import list_bucket_tree, download_bucket_files, login
 
3
  import pandas as pd
4
  import json
5
  import os
6
+ import tempfile
7
  from dotenv import load_dotenv
8
 
 
9
  load_dotenv()
10
  BUCKET_NAME = os.getenv("BUCKET_NAME")
11
+ HF_TOKEN = os.getenv("HF_TOKEN")
12
+ if HF_TOKEN:
13
+ login(token=HF_TOKEN)
14
 
15
  PAGE_SIZE = 5
 
 
 
16
  def extract_customer_data():
17
  try:
18
+ if not BUCKET_NAME:
19
+ print("❌ BUCKET_NAME missing")
20
+ return pd.DataFrame()
21
+
22
+ tree = list_bucket_tree(
23
+ BUCKET_NAME,
24
+ recursive=True,
25
+ token=HF_TOKEN
26
+ )
27
  json_files = [
28
  item.path for item in tree
29
  if item.path.endswith("cameras.json")
 
31
 
32
  if not json_files:
33
  return pd.DataFrame(columns=["customer_id", "customer_name", "customer_email"])
34
+ tmp_dir = tempfile.gettempdir()
35
+ files_map = [
36
+ (f, os.path.join(tmp_dir, f.replace("/", "_")))
37
+ for f in json_files
38
+ ]
39
+ download_bucket_files(
40
+ BUCKET_NAME,
41
+ files=files_map,
42
+ token=HF_TOKEN
43
+ )
44
  rows = []
 
45
  for remote_path, local_path in files_map:
46
  parts = remote_path.split("/")
47
  customer_id = parts[1] if len(parts) > 1 else "unknown"
 
48
  try:
49
  with open(local_path, "r", encoding="utf-8") as f:
50
  data = json.load(f)
 
51
  for item in data:
52
  rows.append({
53
  "customer_id": customer_id,
54
  "customer_name": item.get("customer_name"),
55
  "customer_email": item.get("customer_email")
56
  })
 
57
  except Exception as e:
58
  print(f"File error {remote_path}: {e}")
 
59
  df = pd.DataFrame(rows)
 
 
60
  if not df.empty:
61
+ df = df.drop_duplicates()
 
 
 
62
  return df
 
63
  except Exception as e:
64
+ print("❌ BUCKET ERROR:", e)
65
  return pd.DataFrame(columns=["customer_id", "customer_name", "customer_email"])
66
+ def safe_load():
67
+ try:
68
+ return extract_customer_data()
69
+ except Exception as e:
70
+ print("❌ SAFE LOAD ERROR:", e)
71
  return pd.DataFrame(columns=["customer_id", "customer_name", "customer_email"])
72
+ df_global = safe_load()
73
+ def apply_search(df, email_query):
74
+ if df is None or df.empty:
75
+ return df
76
  if email_query:
77
  df = df[df["customer_email"].astype(str).str.contains(email_query, case=False, na=False)]
 
78
  return df
 
 
 
79
  def build_view(df, page, email_query):
80
  filtered = apply_search(df, email_query)
 
81
  total_pages = max(1, (len(filtered) - 1) // PAGE_SIZE + 1)
82
  page = max(0, min(page, total_pages - 1))
 
83
  start = page * PAGE_SIZE
84
  end = start + PAGE_SIZE
 
85
  paged = filtered.iloc[start:end]
86
+ status = f"Page {page+1}/{total_pages} | Total: {len(filtered)}"
 
 
87
  return paged, page, status
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  with gr.Blocks() as app:
89
  gr.Markdown("# πŸ›° Buck Tracker Customer Dashboard")
 
90
  state_df = gr.State(df_global)
91
  state_page = gr.State(0)
92
+ search_box = gr.Textbox(label="πŸ” Search Email")
 
 
 
 
 
93
  table = gr.Dataframe(
94
  value=build_view(df_global, 0, "")[0],
95
+ interactive=False
 
96
  )
 
97
  status = gr.Textbox(interactive=False)
 
98
  with gr.Row():
99
+ refresh_btn = gr.Button("πŸ”„ Refresh")
100
+ prev_btn = gr.Button("⬅️")
101
+ next_btn = gr.Button("➑️")
102
+ def refresh(email):
103
+ df = safe_load()
104
+ table, page, status_text = build_view(df, 0, email)
105
+ return table, 0, status_text, df
106
+ def next_page(df, page, email):
107
+ return *build_view(df, page + 1, email), df
108
+ def prev_page(df, page, email):
109
+ return *build_view(df, page - 1, email), df
110
  search_box.change(
111
+ fn=lambda df, q: (*build_view(df, 0, q), df),
112
  inputs=[state_df, search_box],
113
  outputs=[table, state_page, status, state_df]
114
  )
 
115
  refresh_btn.click(
116
+ fn=refresh,
117
  inputs=[search_box],
118
  outputs=[table, state_page, status, state_df]
119
  )
 
120
  next_btn.click(
121
  fn=next_page,
122
  inputs=[state_df, state_page, search_box],
123
  outputs=[table, state_page, status, state_df]
124
  )
 
125
  prev_btn.click(
126
  fn=prev_page,
127
  inputs=[state_df, state_page, search_box],
128
  outputs=[table, state_page, status, state_df]
129
  )
130
+ app.queue()
131
  app.launch()