codewithRiz's picture
fix auth
d0aaafd
import gradio as gr
from huggingface_hub import list_bucket_tree, download_bucket_files, login
import pandas as pd
import json
import os
import tempfile
from dotenv import load_dotenv
load_dotenv()
BUCKET_NAME = os.getenv("BUCKET_NAME")
HF_TOKEN = os.getenv("HF_TOKEN")
if HF_TOKEN:
login(token=HF_TOKEN)
PAGE_SIZE = 5
def extract_customer_data():
try:
if not BUCKET_NAME:
print("❌ BUCKET_NAME missing")
return pd.DataFrame()
tree = list_bucket_tree(
BUCKET_NAME,
recursive=True,
token=HF_TOKEN
)
json_files = [
item.path for item in tree
if item.path.endswith("cameras.json")
]
if not json_files:
return pd.DataFrame(columns=["customer_id", "customer_name", "customer_email"])
tmp_dir = tempfile.gettempdir()
files_map = [
(f, os.path.join(tmp_dir, f.replace("/", "_")))
for f in json_files
]
download_bucket_files(
BUCKET_NAME,
files=files_map,
token=HF_TOKEN
)
rows = []
for remote_path, local_path in files_map:
parts = remote_path.split("/")
customer_id = parts[1] if len(parts) > 1 else "unknown"
try:
with open(local_path, "r", encoding="utf-8") as f:
data = json.load(f)
for item in data:
rows.append({
"customer_id": customer_id,
"customer_name": item.get("customer_name"),
"customer_email": item.get("customer_email")
})
except Exception as e:
print(f"File error {remote_path}: {e}")
df = pd.DataFrame(rows)
if not df.empty:
df = df.drop_duplicates()
return df
except Exception as e:
print("❌ BUCKET ERROR:", e)
return pd.DataFrame(columns=["customer_id", "customer_name", "customer_email"])
def safe_load():
try:
return extract_customer_data()
except Exception as e:
print("❌ SAFE LOAD ERROR:", e)
return pd.DataFrame(columns=["customer_id", "customer_name", "customer_email"])
df_global = safe_load()
def apply_search(df, email_query):
if df is None or df.empty:
return df
if email_query:
df = df[df["customer_email"].astype(str).str.contains(email_query, case=False, na=False)]
return df
def build_view(df, page, email_query):
filtered = apply_search(df, email_query)
total_pages = max(1, (len(filtered) - 1) // PAGE_SIZE + 1)
page = max(0, min(page, total_pages - 1))
start = page * PAGE_SIZE
end = start + PAGE_SIZE
paged = filtered.iloc[start:end]
status = f"Page {page+1}/{total_pages} | Total: {len(filtered)}"
return paged, page, status
with gr.Blocks() as app:
gr.Markdown("# πŸ›° Buck Tracker Customer Dashboard")
state_df = gr.State(df_global)
state_page = gr.State(0)
search_box = gr.Textbox(label="πŸ” Search Email")
table = gr.Dataframe(
value=build_view(df_global, 0, "")[0],
interactive=False
)
status = gr.Textbox(interactive=False)
with gr.Row():
refresh_btn = gr.Button("πŸ”„ Refresh")
prev_btn = gr.Button("⬅️")
next_btn = gr.Button("➑️")
def refresh(email):
df = safe_load()
table, page, status_text = build_view(df, 0, email)
return table, 0, status_text, df
def next_page(df, page, email):
return *build_view(df, page + 1, email), df
def prev_page(df, page, email):
return *build_view(df, page - 1, email), df
search_box.change(
fn=lambda df, q: (*build_view(df, 0, q), df),
inputs=[state_df, search_box],
outputs=[table, state_page, status, state_df]
)
refresh_btn.click(
fn=refresh,
inputs=[search_box],
outputs=[table, state_page, status, state_df]
)
next_btn.click(
fn=next_page,
inputs=[state_df, state_page, search_box],
outputs=[table, state_page, status, state_df]
)
prev_btn.click(
fn=prev_page,
inputs=[state_df, state_page, search_box],
outputs=[table, state_page, status, state_df]
)
app.queue()
app.launch()