saim1309 commited on
Commit
acc2582
Β·
verified Β·
1 Parent(s): 1851c09

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -62
app.py CHANGED
@@ -9,8 +9,6 @@ from database import (
9
  from utils import recalculate_all_embeddings
10
  from config import OPENAI_API_KEY
11
 
12
- # Basic Admin Credentials
13
-
14
  from dotenv import load_dotenv
15
 
16
  # Load environment variables
@@ -21,7 +19,8 @@ ADMIN_USER = os.environ.get("ADMIN_USER", "admin")
21
  ADMIN_PASS = os.environ.get("ADMIN_PASS")
22
 
23
  if not ADMIN_PASS:
24
- raise ValueError("CRITICAL SECURITY ERROR: ADMIN_PASS environment variable is not set. Please add it to your Hugging Face Secrets.")
 
25
 
26
  def get_faqs():
27
  data = fetch_all_faq_metadata()
@@ -58,65 +57,126 @@ def run_sync():
58
  except Exception as e:
59
  return f"Sync Failed: {e}"
60
 
61
- with gr.Blocks(title="Get Scene Admin Dashboard") as demo:
62
- gr.Markdown("# 🎭 Get Scene Admin Dashboard")
63
- gr.Markdown("Manage FAQs, Podcasts, and Knowledge Embeddings.")
64
-
65
- with gr.Tabs():
66
- # Tab 1: FAQs
67
- with gr.TabItem("Manage FAQs"):
68
- with gr.Row():
69
- faq_df = gr.Dataframe(
70
- value=get_faqs(),
71
- headers=["id", "question", "answer"],
72
- datatype=["number", "str", "str"],
73
- interactive=True,
74
- label="FAQ Database"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  )
76
-
77
- with gr.Row():
78
- with gr.Column():
79
- gr.Markdown("### Add New FAQ")
80
- new_q = gr.Textbox(label="Question")
81
- new_a = gr.TextArea(label="Answer")
82
- add_btn = gr.Button("Add Entry", variant="primary")
83
-
84
- with gr.Column():
85
- gr.Markdown("### Bulk Upload")
86
- faq_file = gr.File(label="Upload CSV/Excel (Columns: Question, Answer)")
87
- upload_faq_btn = gr.Button("Bulk Upload FAQs")
88
- faq_upload_status = gr.Textbox(label="Status", interactive=False)
89
-
90
- def add_and_refresh(q, a):
91
- add_faq_entry(q, a)
92
- return get_faqs(), "", ""
93
-
94
- add_btn.click(add_and_refresh, [new_q, new_a], [faq_df, new_q, new_a])
95
- upload_faq_btn.click(handle_faq_upload, [faq_file], [faq_upload_status])
96
-
97
- # Tab 2: Podcasts
98
- with gr.TabItem("Podcasts"):
99
- pod_df = gr.Dataframe(
100
- value=get_podcasts(),
101
- headers=["id", "guest_name", "youtube_url", "summary"],
102
- datatype=["number", "str", "str", "str"],
103
- label="Podcast Episodes"
104
- )
105
- gr.Markdown("### Bulk Upload Podcasts")
106
- pod_file = gr.File(label="Upload CSV/Excel (Columns: Guest Name, YouTube URL, Summary)")
107
- upload_pod_btn = gr.Button("Bulk Upload Podcasts")
108
- pod_upload_status = gr.Textbox(label="Status", interactive=False)
109
-
110
- upload_pod_btn.click(handle_podcast_upload, [pod_file], [pod_upload_status])
111
-
112
- # Tab 3: Sync
113
- with gr.TabItem("Sync & Embed"):
114
- gr.Markdown("### Recalculate Embeddings")
115
- gr.Markdown("When you change text or upload new data, the 'embeddings' (AI understanding) must be recalculated for the chatbot to recognize the new information.")
116
- sync_btn = gr.Button("πŸ”„ Sync & Recalculate Embeddings", variant="primary", scale=2)
117
- sync_status = gr.Textbox(label="Sync Status", interactive=False)
118
-
119
- sync_btn.click(run_sync, None, [sync_status])
120
 
121
  if __name__ == "__main__":
122
- demo.launch(auth=(ADMIN_USER, ADMIN_PASS), server_name="0.0.0.0")
 
 
9
  from utils import recalculate_all_embeddings
10
  from config import OPENAI_API_KEY
11
 
 
 
12
  from dotenv import load_dotenv
13
 
14
  # Load environment variables
 
19
  ADMIN_PASS = os.environ.get("ADMIN_PASS")
20
 
21
  if not ADMIN_PASS:
22
+ raise ValueError("CRITICAL SECURITY ERROR: ADMIN_PASS environment variable is not set.")
23
+
24
 
25
  def get_faqs():
26
  data = fetch_all_faq_metadata()
 
57
  except Exception as e:
58
  return f"Sync Failed: {e}"
59
 
60
+ def check_login(username, password):
61
+ """Validate credentials and return visibility updates."""
62
+ if username == ADMIN_USER and password == ADMIN_PASS:
63
+ return (
64
+ gr.update(visible=False), # Hide login panel
65
+ gr.update(visible=True), # Show dashboard
66
+ "" # Clear error message
67
+ )
68
+ else:
69
+ return (
70
+ gr.update(visible=True), # Keep login panel visible
71
+ gr.update(visible=False), # Keep dashboard hidden
72
+ "❌ Invalid username or password."
73
+ )
74
+
75
+ def logout():
76
+ """Log out and show login panel again."""
77
+ return (
78
+ gr.update(visible=True), # Show login panel
79
+ gr.update(visible=False), # Hide dashboard
80
+ "", # Clear username
81
+ "" # Clear password
82
+ )
83
+
84
+
85
+ with gr.Blocks(title="Get Scene Admin Dashboard", theme=gr.themes.Base()) as demo:
86
+
87
+ # ── LOGIN PANEL ──────────────────────────────────────────────
88
+ with gr.Column(visible=True, elem_id="login_panel") as login_panel:
89
+ gr.Markdown("# 🎭 Get Scene Admin\nPlease log in to continue.")
90
+ login_user = gr.Textbox(label="Username", placeholder="Enter username")
91
+ login_pass = gr.Textbox(label="Password", placeholder="Enter password", type="password")
92
+ login_error = gr.Markdown("", visible=True)
93
+ login_btn = gr.Button("Log In", variant="primary")
94
+
95
+ # ── DASHBOARD (hidden until login) ───────────────────────────
96
+ with gr.Column(visible=False) as dashboard:
97
+ with gr.Row():
98
+ gr.Markdown("# 🎭 Get Scene Admin Dashboard")
99
+ logout_btn = gr.Button("Log Out", variant="stop", scale=0)
100
+
101
+ gr.Markdown("Manage FAQs, Podcasts, and Knowledge Embeddings.")
102
+
103
+ with gr.Tabs():
104
+ # Tab 1: FAQs
105
+ with gr.TabItem("Manage FAQs"):
106
+ with gr.Row():
107
+ faq_df = gr.Dataframe(
108
+ value=get_faqs,
109
+ headers=["id", "question", "answer"],
110
+ datatype=["number", "str", "str"],
111
+ interactive=True,
112
+ label="FAQ Database"
113
+ )
114
+
115
+ with gr.Row():
116
+ with gr.Column():
117
+ gr.Markdown("### Add New FAQ")
118
+ new_q = gr.Textbox(label="Question")
119
+ new_a = gr.TextArea(label="Answer")
120
+ add_btn = gr.Button("Add Entry", variant="primary")
121
+
122
+ with gr.Column():
123
+ gr.Markdown("### Bulk Upload")
124
+ faq_file = gr.File(label="Upload CSV/Excel (Columns: Question, Answer)")
125
+ upload_faq_btn = gr.Button("Bulk Upload FAQs")
126
+ faq_upload_status = gr.Textbox(label="Status", interactive=False)
127
+
128
+ def add_and_refresh(q, a):
129
+ add_faq_entry(q, a)
130
+ return get_faqs(), "", ""
131
+
132
+ add_btn.click(add_and_refresh, [new_q, new_a], [faq_df, new_q, new_a])
133
+ upload_faq_btn.click(handle_faq_upload, [faq_file], [faq_upload_status])
134
+
135
+ # Tab 2: Podcasts
136
+ with gr.TabItem("Podcasts"):
137
+ pod_df = gr.Dataframe(
138
+ value=get_podcasts,
139
+ headers=["id", "guest_name", "youtube_url", "summary"],
140
+ datatype=["number", "str", "str", "str"],
141
+ label="Podcast Episodes"
142
  )
143
+ gr.Markdown("### Bulk Upload Podcasts")
144
+ pod_file = gr.File(label="Upload CSV/Excel (Columns: Guest Name, YouTube URL, Summary)")
145
+ upload_pod_btn = gr.Button("Bulk Upload Podcasts")
146
+ pod_upload_status = gr.Textbox(label="Status", interactive=False)
147
+
148
+ upload_pod_btn.click(handle_podcast_upload, [pod_file], [pod_upload_status])
149
+
150
+ # Tab 3: Sync
151
+ with gr.TabItem("Sync & Embed"):
152
+ gr.Markdown("### Recalculate Embeddings")
153
+ gr.Markdown("When you change text or upload new data, the 'embeddings' (AI understanding) must be recalculated for the chatbot to recognize the new information.")
154
+ sync_btn = gr.Button("πŸ”„ Sync & Recalculate Embeddings", variant="primary", scale=2)
155
+ sync_status = gr.Textbox(label="Sync Status", interactive=False)
156
+
157
+ sync_btn.click(run_sync, None, [sync_status])
158
+
159
+ # ── WIRING ────────────────────────────────────────────────────
160
+ login_btn.click(
161
+ check_login,
162
+ inputs=[login_user, login_pass],
163
+ outputs=[login_panel, dashboard, login_error]
164
+ )
165
+
166
+ # Allow pressing Enter in password field to log in
167
+ login_pass.submit(
168
+ check_login,
169
+ inputs=[login_user, login_pass],
170
+ outputs=[login_panel, dashboard, login_error]
171
+ )
172
+
173
+ logout_btn.click(
174
+ logout,
175
+ inputs=None,
176
+ outputs=[login_panel, dashboard, login_user, login_pass]
177
+ )
178
+
 
 
 
 
 
 
 
 
179
 
180
  if __name__ == "__main__":
181
+ # No auth= parameter β€” login is handled inside the app
182
+ demo.launch(server_name="0.0.0.0")