Spaces:
Running
Running
debug: add load handler logging + auth_message removed
Browse files- Wrap load_settings_on_startup and load_session_state_on_startup in
try/except with print logging so HF logs show the actual error
- Both handlers now return safe defaults on failure instead of crashing
- Removed auth_message from launch()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- app.py +1 -0
- chat_interface.py +113 -27
app.py
CHANGED
|
@@ -49,5 +49,6 @@ app.launch(
|
|
| 49 |
share=False,
|
| 50 |
inbrowser=False,
|
| 51 |
auth=authenticate_user,
|
|
|
|
| 52 |
show_api=False,
|
| 53 |
)
|
|
|
|
| 49 |
share=False,
|
| 50 |
inbrowser=False,
|
| 51 |
auth=authenticate_user,
|
| 52 |
+
|
| 53 |
show_api=False,
|
| 54 |
)
|
chat_interface.py
CHANGED
|
@@ -4265,11 +4265,27 @@ def create_chat_interface():
|
|
| 4265 |
current_usecase = gr.State(default_settings['use_case'])
|
| 4266 |
current_liveboard_name = gr.State(default_settings.get('liveboard_name', ''))
|
| 4267 |
|
| 4268 |
-
# Header
|
| 4269 |
-
gr.
|
| 4270 |
-
|
| 4271 |
-
|
| 4272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4273 |
|
| 4274 |
# Additional state for new tabs
|
| 4275 |
ai_feedback_state = gr.State("")
|
|
@@ -4752,31 +4768,53 @@ def create_chat_interface():
|
|
| 4752 |
# Load settings from Supabase on startup (uses SETTINGS_SCHEMA)
|
| 4753 |
def load_settings_on_startup(request: gr.Request = None):
|
| 4754 |
"""Load saved settings from Supabase - uses schema-driven helper"""
|
| 4755 |
-
|
| 4756 |
-
|
| 4757 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4758 |
|
| 4759 |
def load_session_state_on_startup(request: gr.Request = None):
|
| 4760 |
"""Initialize chat/session state from the same authenticated user settings."""
|
| 4761 |
-
|
| 4762 |
-
|
| 4763 |
-
|
| 4764 |
-
|
| 4765 |
-
|
| 4766 |
-
|
| 4767 |
-
|
| 4768 |
-
|
| 4769 |
|
| 4770 |
-
|
| 4771 |
-
"
|
| 4772 |
-
model,
|
| 4773 |
-
|
| 4774 |
-
|
| 4775 |
-
|
| 4776 |
-
|
| 4777 |
-
|
| 4778 |
-
|
| 4779 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4780 |
|
| 4781 |
# Wire up load handler - outputs follow SETTINGS_SCHEMA order
|
| 4782 |
interface.load(
|
|
@@ -5412,7 +5450,54 @@ def create_settings_tab():
|
|
| 5412 |
inputs=[],
|
| 5413 |
outputs=[settings_status]
|
| 5414 |
)
|
| 5415 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5416 |
# Return components dict for loading (follows schema order)
|
| 5417 |
return all_components
|
| 5418 |
|
|
@@ -5474,6 +5559,7 @@ if __name__ == "__main__":
|
|
| 5474 |
inbrowser=False,
|
| 5475 |
debug=True,
|
| 5476 |
auth=auth_fn,
|
|
|
|
| 5477 |
max_threads=20 # Allow multiple threads for concurrent requests
|
| 5478 |
)
|
| 5479 |
|
|
|
|
| 4265 |
current_usecase = gr.State(default_settings['use_case'])
|
| 4266 |
current_liveboard_name = gr.State(default_settings.get('liveboard_name', ''))
|
| 4267 |
|
| 4268 |
+
# Header with logout link
|
| 4269 |
+
with gr.Row(equal_height=True):
|
| 4270 |
+
gr.Markdown("""
|
| 4271 |
+
# π¬ ThoughtSpot Demo Builder
|
| 4272 |
+
### AI-Powered Conversational Demo Creation
|
| 4273 |
+
""")
|
| 4274 |
+
gr.HTML("""
|
| 4275 |
+
<div style="display:flex; align-items:center; justify-content:flex-end; padding:8px 0;">
|
| 4276 |
+
<a href="/logout" style="
|
| 4277 |
+
color: #6b7280;
|
| 4278 |
+
text-decoration: none;
|
| 4279 |
+
font-size: 14px;
|
| 4280 |
+
padding: 6px 14px;
|
| 4281 |
+
border: 1px solid #d1d5db;
|
| 4282 |
+
border-radius: 6px;
|
| 4283 |
+
white-space: nowrap;
|
| 4284 |
+
" onmouseover="this.style.background='#f3f4f6'" onmouseout="this.style.background='transparent'">
|
| 4285 |
+
Sign Out β
|
| 4286 |
+
</a>
|
| 4287 |
+
</div>
|
| 4288 |
+
""")
|
| 4289 |
|
| 4290 |
# Additional state for new tabs
|
| 4291 |
ai_feedback_state = gr.State("")
|
|
|
|
| 4768 |
# Load settings from Supabase on startup (uses SETTINGS_SCHEMA)
|
| 4769 |
def load_settings_on_startup(request: gr.Request = None):
|
| 4770 |
"""Load saved settings from Supabase - uses schema-driven helper"""
|
| 4771 |
+
try:
|
| 4772 |
+
user_email = require_authenticated_email(request)
|
| 4773 |
+
print(f"[LOAD] load_settings_on_startup for {user_email}")
|
| 4774 |
+
settings = load_gradio_settings(user_email)
|
| 4775 |
+
result = load_settings_values(settings, user_email)
|
| 4776 |
+
print(f"[LOAD] load_settings_on_startup OK β {len(result)} values")
|
| 4777 |
+
return result
|
| 4778 |
+
except Exception as e:
|
| 4779 |
+
import traceback
|
| 4780 |
+
print(f"[LOAD ERROR] load_settings_on_startup failed: {e}\n{traceback.format_exc()}")
|
| 4781 |
+
# Return schema-length list of defaults so Gradio doesn't crash
|
| 4782 |
+
return [default for _, _, default, _ in SETTINGS_SCHEMA]
|
| 4783 |
|
| 4784 |
def load_session_state_on_startup(request: gr.Request = None):
|
| 4785 |
"""Initialize chat/session state from the same authenticated user settings."""
|
| 4786 |
+
try:
|
| 4787 |
+
user_email = require_authenticated_email(request)
|
| 4788 |
+
print(f"[LOAD] load_session_state_on_startup for {user_email}")
|
| 4789 |
+
except Exception as e:
|
| 4790 |
+
print(f"[LOAD ERROR] load_session_state_on_startup auth failed: {e}")
|
| 4791 |
+
user_email = ""
|
| 4792 |
+
try:
|
| 4793 |
+
settings = load_gradio_settings(user_email)
|
| 4794 |
|
| 4795 |
+
company = (str(settings.get("default_company_url", "")).strip() or "Amazon.com")
|
| 4796 |
+
use_case = (str(settings.get("default_use_case", "")).strip() or "Sales Analytics")
|
| 4797 |
+
model = (str(settings.get("default_llm", "")).strip() or DEFAULT_LLM_MODEL)
|
| 4798 |
+
liveboard_name = str(settings.get("liveboard_name", "")).strip()
|
| 4799 |
+
initial_message = build_initial_chat_message(company, use_case)
|
| 4800 |
+
print(f"[LOAD] load_session_state_on_startup OK β model={model}, company={company}")
|
| 4801 |
+
return (
|
| 4802 |
+
"initialization",
|
| 4803 |
+
model,
|
| 4804 |
+
company,
|
| 4805 |
+
use_case,
|
| 4806 |
+
liveboard_name,
|
| 4807 |
+
gr.update(value=model),
|
| 4808 |
+
gr.update(value=liveboard_name),
|
| 4809 |
+
initial_message,
|
| 4810 |
+
)
|
| 4811 |
+
except Exception as e:
|
| 4812 |
+
import traceback
|
| 4813 |
+
print(f"[LOAD ERROR] load_session_state_on_startup failed: {e}\n{traceback.format_exc()}")
|
| 4814 |
+
return (
|
| 4815 |
+
"initialization", DEFAULT_LLM_MODEL, "Amazon.com", "Sales Analytics", "",
|
| 4816 |
+
gr.update(value=DEFAULT_LLM_MODEL), gr.update(value=""), "",
|
| 4817 |
+
)
|
| 4818 |
|
| 4819 |
# Wire up load handler - outputs follow SETTINGS_SCHEMA order
|
| 4820 |
interface.load(
|
|
|
|
| 5450 |
inputs=[],
|
| 5451 |
outputs=[settings_status]
|
| 5452 |
)
|
| 5453 |
+
|
| 5454 |
+
# -----------------------------------------------------------------------
|
| 5455 |
+
# Change Password
|
| 5456 |
+
# -----------------------------------------------------------------------
|
| 5457 |
+
gr.Markdown("---")
|
| 5458 |
+
with gr.Accordion("π Change Password", open=False):
|
| 5459 |
+
with gr.Row():
|
| 5460 |
+
with gr.Column(scale=1):
|
| 5461 |
+
cp_current = gr.Textbox(label="Current Password", type="password", placeholder="Your current password")
|
| 5462 |
+
cp_new = gr.Textbox(label="New Password", type="password", placeholder="At least 8 characters")
|
| 5463 |
+
cp_confirm = gr.Textbox(label="Confirm New Password", type="password", placeholder="Repeat new password")
|
| 5464 |
+
cp_btn = gr.Button("Change Password", variant="primary")
|
| 5465 |
+
cp_status = gr.Markdown("")
|
| 5466 |
+
with gr.Column(scale=1):
|
| 5467 |
+
gr.Markdown("""
|
| 5468 |
+
**Password requirements:**
|
| 5469 |
+
- At least 8 characters
|
| 5470 |
+
- Current password required to confirm identity
|
| 5471 |
+
|
| 5472 |
+
*Forgot your password? Ask an admin to reset it via the Admin tab, then change it here after signing in.*
|
| 5473 |
+
""")
|
| 5474 |
+
|
| 5475 |
+
def change_password_handler(current, new_pw, confirm, request: gr.Request = None):
|
| 5476 |
+
if not current or not new_pw or not confirm:
|
| 5477 |
+
return "β All fields are required."
|
| 5478 |
+
if new_pw != confirm:
|
| 5479 |
+
return "β New passwords don't match."
|
| 5480 |
+
if len(new_pw) < 8:
|
| 5481 |
+
return "β New password must be at least 8 characters."
|
| 5482 |
+
try:
|
| 5483 |
+
user_email = require_authenticated_email(request)
|
| 5484 |
+
from supabase_client import UserManager
|
| 5485 |
+
um = UserManager()
|
| 5486 |
+
if not um.enabled:
|
| 5487 |
+
return "β οΈ Supabase not configured β password change unavailable."
|
| 5488 |
+
if not um.authenticate(user_email, current):
|
| 5489 |
+
return "β Current password is incorrect."
|
| 5490 |
+
um.reset_password(user_email, new_pw)
|
| 5491 |
+
return "β
Password changed successfully. Use your new password next time you sign in."
|
| 5492 |
+
except Exception as e:
|
| 5493 |
+
return f"β Error: {e}"
|
| 5494 |
+
|
| 5495 |
+
cp_btn.click(
|
| 5496 |
+
fn=change_password_handler,
|
| 5497 |
+
inputs=[cp_current, cp_new, cp_confirm],
|
| 5498 |
+
outputs=[cp_status]
|
| 5499 |
+
)
|
| 5500 |
+
|
| 5501 |
# Return components dict for loading (follows schema order)
|
| 5502 |
return all_components
|
| 5503 |
|
|
|
|
| 5559 |
inbrowser=False,
|
| 5560 |
debug=True,
|
| 5561 |
auth=auth_fn,
|
| 5562 |
+
|
| 5563 |
max_threads=20 # Allow multiple threads for concurrent requests
|
| 5564 |
)
|
| 5565 |
|