Nischal Subedi
commited on
Commit
·
ed73032
1
Parent(s):
b9b1527
UI update
Browse files
app.py
CHANGED
@@ -249,16 +249,16 @@ Answer:"""
|
|
249 |
# Basic client-side validation for immediate feedback (redundant but good UX)
|
250 |
if not api_key or not api_key.strip() or not api_key.startswith("sk-"):
|
251 |
return "<div class='error-message'><span class='error-icon'></span>Please provide a valid OpenAI API key (starting with 'sk-'). <a href='https://platform.openai.com/api-keys' target='_blank'>OpenAI</a>.</div>"
|
252 |
-
if not state or state is None or
|
253 |
return "<div class='error-message'><span class='error-icon'></span>Please select a valid state from the list.</div>"
|
254 |
if not query or not query.strip():
|
255 |
return "<div class='error-message'><span class='error-icon'></span>Please enter your question in the text box.</div>"
|
256 |
|
257 |
-
# Call the core processing logic
|
258 |
result = self.process_query(query=query, state=state, openai_api_key=api_key)
|
259 |
answer = result.get("answer", "<div class='error-message'><span class='error-icon'>⚠️</span>An unexpected error occurred.</div>")
|
260 |
|
261 |
-
# Check if the answer already contains an error message
|
262 |
if "<div class='error-message'>" in answer:
|
263 |
return answer
|
264 |
else:
|
@@ -287,10 +287,12 @@ Answer:"""
|
|
287 |
example_queries = []
|
288 |
if radio_choices and "Error" not in radio_choices[0] and len(radio_choices) > 0:
|
289 |
loaded_states_set = set(radio_choices)
|
|
|
290 |
example_queries = [ex for ex in example_queries_base if ex[1] in loaded_states_set]
|
291 |
-
if not example_queries
|
|
|
292 |
example_queries.append(["What basic rights do tenants have?", radio_choices[0]])
|
293 |
-
else: # If states failed to load, provide a generic example
|
294 |
example_queries.append(["What basic rights do tenants have?", "California"])
|
295 |
|
296 |
|
@@ -298,64 +300,99 @@ Answer:"""
|
|
298 |
/* Import legible fonts from Google Fonts */
|
299 |
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Poppins:wght@600;700;800&display=swap');
|
300 |
|
301 |
-
/*
|
302 |
-
:root
|
303 |
--primary-color: #FF8C00;
|
304 |
--primary-hover: #E07B00;
|
305 |
-
--background-primary: hsl(30, 100%, 99.9%);
|
306 |
-
--background-secondary: hsl(30, 100%, 96%);
|
307 |
-
--text-primary: #4A3C32;
|
308 |
-
--text-secondary: #8C7B6F;
|
309 |
-
--border-color: hsl(30, 70%, 85%);
|
310 |
-
--border-focus: #FF8C00;
|
311 |
--shadow-sm: 0 1px 3px rgba(0,0,0,0.08);
|
312 |
--shadow-md: 0 4px 10px rgba(0,0,0,0.1);
|
313 |
--shadow-lg: 0 10px 20px rgba(0,0,0,0.15);
|
314 |
-
--error-bg: #FFF0E0;
|
315 |
-
--error-border: #FFD2B2;
|
316 |
-
--error-text: #E05C00;
|
|
|
317 |
|
318 |
-
|
|
|
|
|
|
|
|
|
319 |
--background-fill-primary: var(--background-primary) !important;
|
320 |
--background-fill-secondary: var(--background-secondary) !important;
|
321 |
--background-fill-tertiary: var(--background-secondary) !important; /* For less prominent backgrounds */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
322 |
--text-color-subdued: var(--text-secondary) !important;
|
323 |
--text-color-highlight: var(--primary-color) !important;
|
324 |
-
--text-color-body: var(--text-primary) !important;
|
325 |
--text-color-placeholder: var(--text-secondary) !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
326 |
--border-color-primary: var(--border-color) !important;
|
327 |
--border-color-accent: var(--border-focus) !important;
|
328 |
-
--
|
329 |
-
--
|
330 |
-
--
|
|
|
|
|
|
|
331 |
--button-primary-background: var(--primary-color) !important;
|
332 |
--button-primary-background-hover: var(--primary-hover) !important;
|
|
|
333 |
--button-secondary-background: transparent !important;
|
334 |
--button-secondary-background-hover: var(--background-secondary) !important;
|
335 |
--button-secondary-border-color: var(--border-color) !important;
|
336 |
--button-secondary-border-color-hover: var(--primary-color) !important;
|
337 |
-
--
|
338 |
-
--input-border-color: var(--border-color) !important;
|
339 |
-
--input-border-color-focus: var(--border-focus) !important;
|
340 |
-
--block-background: var(--background-primary) !important;
|
341 |
-
--block-border-color: var(--border-color) !important;
|
342 |
-
--panel-background: var(--background-primary) !important;
|
343 |
-
--color-text-primary: var(--text-primary) !important;
|
344 |
-
--color-text-secondary: var(--text-secondary) !important;
|
345 |
-
--color-border-primary: var(--border-color) !important;
|
346 |
-
--color-border-secondary: var(--border-color) !important;
|
347 |
--color-button-primary-background: var(--primary-color) !important;
|
348 |
--color-button-primary-background-hover: var(--primary-hover) !important;
|
349 |
--color-button-secondary-background: transparent !important;
|
350 |
--color-button-secondary-background-hover: var(--background-secondary) !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
351 |
--color-accent-soft: rgba(255, 140, 0, 0.2) !important; /* Used for focus shadows */
|
|
|
|
|
|
|
352 |
}}
|
353 |
|
|
|
354 |
body, html {{
|
355 |
background-color: var(--background-secondary) !important;
|
356 |
color: var(--text-primary) !important;
|
357 |
-
transition: none !important; /* Prevent theme change transitions */
|
358 |
}}
|
|
|
|
|
359 |
.gradio-container {{
|
360 |
max-width: 900px !important;
|
361 |
margin: 0 auto !important;
|
@@ -368,6 +405,7 @@ Answer:"""
|
|
368 |
.main-dashboard-container > * {{
|
369 |
background-color: var(--background-primary) !important;
|
370 |
border-color: var(--border-color) !important; /* Ensure card borders are consistent */
|
|
|
371 |
}}
|
372 |
.app-header-wrapper {{
|
373 |
background: linear-gradient(145deg, var(--background-primary) 0%, var(--background-secondary) 100%) !important;
|
@@ -502,10 +540,18 @@ Answer:"""
|
|
502 |
font-weight: 700 !important;
|
503 |
color: var(--primary-color) !important;
|
504 |
}}
|
|
|
505 |
.gr-block, .gr-box, .gr-prose, .gr-form, .gr-panel,
|
506 |
-
.gr-columns, .gr-column
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
507 |
.gradio-html, .gradio-markdown, .gradio-textbox, .gradio-radio, .gradio-button {{
|
508 |
-
background-color: transparent !important;
|
509 |
color: var(--text-primary) !important;
|
510 |
white-space: normal !important;
|
511 |
overflow-wrap: break-word;
|
@@ -528,7 +574,7 @@ Answer:"""
|
|
528 |
padding: 0.85rem 1rem !important;
|
529 |
font-size: 0.98rem !important;
|
530 |
font-family: 'Inter', sans-serif !important;
|
531 |
-
color: var(--text-primary) !important;
|
532 |
transition: border-color 0.2s ease, box-shadow 0.2s ease !important;
|
533 |
box-shadow: var(--shadow-sm) !important;
|
534 |
}}
|
@@ -856,9 +902,8 @@ Answer:"""
|
|
856 |
}}
|
857 |
"""
|
858 |
|
859 |
-
#
|
860 |
-
|
861 |
-
with gr.Blocks(css=custom_css, title="Landlord-Tenant Rights Assistant", theme_mode="light") as demo:
|
862 |
with gr.Group(elem_classes="app-header-wrapper"):
|
863 |
gr.Markdown(
|
864 |
"""
|
|
|
249 |
# Basic client-side validation for immediate feedback (redundant but good UX)
|
250 |
if not api_key or not api_key.strip() or not api_key.startswith("sk-"):
|
251 |
return "<div class='error-message'><span class='error-icon'></span>Please provide a valid OpenAI API key (starting with 'sk-'). <a href='https://platform.openai.com/api-keys' target='_blank'>OpenAI</a>.</div>"
|
252 |
+
if not state or state is None or "Error" in state: # Check for error states
|
253 |
return "<div class='error-message'><span class='error-icon'></span>Please select a valid state from the list.</div>"
|
254 |
if not query or not query.strip():
|
255 |
return "<div class='error-message'><span class='error-icon'></span>Please enter your question in the text box.</div>"
|
256 |
|
257 |
+
# Call the core processing logic using 'self'
|
258 |
result = self.process_query(query=query, state=state, openai_api_key=api_key)
|
259 |
answer = result.get("answer", "<div class='error-message'><span class='error-icon'>⚠️</span>An unexpected error occurred.</div>")
|
260 |
|
261 |
+
# Check if the answer already contains an error message from process_query
|
262 |
if "<div class='error-message'>" in answer:
|
263 |
return answer
|
264 |
else:
|
|
|
287 |
example_queries = []
|
288 |
if radio_choices and "Error" not in radio_choices[0] and len(radio_choices) > 0:
|
289 |
loaded_states_set = set(radio_choices)
|
290 |
+
# Filter examples to only include states that were successfully loaded
|
291 |
example_queries = [ex for ex in example_queries_base if ex[1] in loaded_states_set]
|
292 |
+
if not example_queries and radio_choices[0] != "Error: States unavailable":
|
293 |
+
# Fallback if no matching examples found, use the first available state
|
294 |
example_queries.append(["What basic rights do tenants have?", radio_choices[0]])
|
295 |
+
else: # If states failed to load, provide a generic example (e.g., California)
|
296 |
example_queries.append(["What basic rights do tenants have?", "California"])
|
297 |
|
298 |
|
|
|
300 |
/* Import legible fonts from Google Fonts */
|
301 |
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Poppins:wght@600;700;800&display=swap');
|
302 |
|
303 |
+
/* Define light theme variables */
|
304 |
+
:root {{
|
305 |
--primary-color: #FF8C00;
|
306 |
--primary-hover: #E07B00;
|
307 |
+
--background-primary: hsl(30, 100%, 99.9%); /* Near white, slightly warm */
|
308 |
+
--background-secondary: hsl(30, 100%, 96%); /* Slightly darker background */
|
309 |
+
--text-primary: #4A3C32; /* Dark brown/off-black for main text */
|
310 |
+
--text-secondary: #8C7B6F; /* Lighter brown/gray for subdued text */
|
311 |
+
--border-color: hsl(30, 70%, 85%); /* Light brown/peach border */
|
312 |
+
--border-focus: #FF8C00; /* Primary color for focus */
|
313 |
--shadow-sm: 0 1px 3px rgba(0,0,0,0.08);
|
314 |
--shadow-md: 0 4px 10px rgba(0,0,0,0.1);
|
315 |
--shadow-lg: 0 10px 20px rgba(0,0,0,0.15);
|
316 |
+
--error-bg: #FFF0E0; /* Light peach error background */
|
317 |
+
--error-border: #FFD2B2; /* Peach error border */
|
318 |
+
--error-text: #E05C00; /* Orange-red error text */
|
319 |
+
}}
|
320 |
|
321 |
+
/* IMPORTANT: Force Gradio's internal variables to use our light theme values for both light and dark modes */
|
322 |
+
/* This is the key to override system theme preference without using theme_mode */
|
323 |
+
/* Targeting :root, html.dark, body.dark, and .dark ensures maximum override */
|
324 |
+
:root, html.dark, body.dark, .dark {{
|
325 |
+
/* General backgrounds */
|
326 |
--background-fill-primary: var(--background-primary) !important;
|
327 |
--background-fill-secondary: var(--background-secondary) !important;
|
328 |
--background-fill-tertiary: var(--background-secondary) !important; /* For less prominent backgrounds */
|
329 |
+
--panel-background: var(--background-primary) !important;
|
330 |
+
--block-background: var(--background-primary) !important;
|
331 |
+
--color-background-primary: var(--background-primary) !important;
|
332 |
+
--color-background-secondary: var(--background-secondary) !important;
|
333 |
+
|
334 |
+
/* Text colors */
|
335 |
+
--text-color-body: var(--text-primary) !important;
|
336 |
--text-color-subdued: var(--text-secondary) !important;
|
337 |
--text-color-highlight: var(--primary-color) !important;
|
|
|
338 |
--text-color-placeholder: var(--text-secondary) !important;
|
339 |
+
--text-color-link: var(--primary-color) !important; /* For links */
|
340 |
+
--color-text-primary: var(--text-primary) !important;
|
341 |
+
--color-text-secondary: var(--text-secondary) !important;
|
342 |
+
--color-text-placeholder: var(--text-secondary) !important;
|
343 |
+
|
344 |
+
/* Border colors */
|
345 |
--border-color-primary: var(--border-color) !important;
|
346 |
--border-color-accent: var(--border-focus) !important;
|
347 |
+
--border-color-secondary: var(--border-color) !important;
|
348 |
+
--border-color-tertiary: var(--border-color) !important;
|
349 |
+
--color-border-primary: var(--border-color) !important;
|
350 |
+
--color-border-secondary: var(--border-color) !important;
|
351 |
+
|
352 |
+
/* Button colors */
|
353 |
--button-primary-background: var(--primary-color) !important;
|
354 |
--button-primary-background-hover: var(--primary-hover) !important;
|
355 |
+
--button-primary-text-color: white !important; /* Ensure text is white on primary buttons */
|
356 |
--button-secondary-background: transparent !important;
|
357 |
--button-secondary-background-hover: var(--background-secondary) !important;
|
358 |
--button-secondary-border-color: var(--border-color) !important;
|
359 |
--button-secondary-border-color-hover: var(--primary-color) !important;
|
360 |
+
--button-secondary-text-color: var(--text-primary) !important; /* Ensure text color for secondary */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
--color-button-primary-background: var(--primary-color) !important;
|
362 |
--color-button-primary-background-hover: var(--primary-hover) !important;
|
363 |
--color-button-secondary-background: transparent !important;
|
364 |
--color-button-secondary-background-hover: var(--background-secondary) !important;
|
365 |
+
--color-button-primary-text: white !important;
|
366 |
+
--color-button-secondary-text: var(--text-primary) !important;
|
367 |
+
|
368 |
+
/* Input specific */
|
369 |
+
--input-background-fill: var(--background-primary) !important;
|
370 |
+
--input-border-color: var(--border-color) !important;
|
371 |
+
--input-border-color-focus: var(--border-focus) !important;
|
372 |
+
--input-shadow: var(--shadow-sm) !important; /* For textboxes */
|
373 |
+
--input-shadow-focus: 0 0 0 4px rgba(255, 140, 0, 0.2) !important;
|
374 |
+
--input-text-color: var(--text-primary) !important;
|
375 |
+
|
376 |
+
/* Shadows */
|
377 |
+
--shadow-s: var(--shadow-sm) !important;
|
378 |
+
--shadow-m: var(--shadow-md) !important;
|
379 |
+
--shadow-l: var(--shadow-lg) !important;
|
380 |
+
|
381 |
+
/* Misc */
|
382 |
--color-accent-soft: rgba(255, 140, 0, 0.2) !important; /* Used for focus shadows */
|
383 |
+
--color-error: var(--error-text) !important; /* For error messages */
|
384 |
+
--color-error-background: var(--error-bg) !important;
|
385 |
+
--color-error-border: var(--error-border) !important;
|
386 |
}}
|
387 |
|
388 |
+
/* Base styles for html and body */
|
389 |
body, html {{
|
390 |
background-color: var(--background-secondary) !important;
|
391 |
color: var(--text-primary) !important;
|
392 |
+
transition: none !important; /* Prevent any Gradio theme change transitions */
|
393 |
}}
|
394 |
+
|
395 |
+
/* General Gradio container and element overrides */
|
396 |
.gradio-container {{
|
397 |
max-width: 900px !important;
|
398 |
margin: 0 auto !important;
|
|
|
405 |
.main-dashboard-container > * {{
|
406 |
background-color: var(--background-primary) !important;
|
407 |
border-color: var(--border-color) !important; /* Ensure card borders are consistent */
|
408 |
+
color: var(--text-primary) !important;
|
409 |
}}
|
410 |
.app-header-wrapper {{
|
411 |
background: linear-gradient(145deg, var(--background-primary) 0%, var(--background-secondary) 100%) !important;
|
|
|
540 |
font-weight: 700 !important;
|
541 |
color: var(--primary-color) !important;
|
542 |
}}
|
543 |
+
/* More specific overrides for Gradio components */
|
544 |
.gr-block, .gr-box, .gr-prose, .gr-form, .gr-panel,
|
545 |
+
.gr-columns, .gr-column {{
|
546 |
+
background-color: var(--background-primary) !important;
|
547 |
+
color: var(--text-primary) !important;
|
548 |
+
border-color: var(--border-color) !important; /* Ensure consistent borders */
|
549 |
+
white-space: normal !important;
|
550 |
+
overflow-wrap: break-word;
|
551 |
+
word-break: break-word;
|
552 |
+
}}
|
553 |
.gradio-html, .gradio-markdown, .gradio-textbox, .gradio-radio, .gradio-button {{
|
554 |
+
background-color: transparent !important; /* Let parent background control this */
|
555 |
color: var(--text-primary) !important;
|
556 |
white-space: normal !important;
|
557 |
overflow-wrap: break-word;
|
|
|
574 |
padding: 0.85rem 1rem !important;
|
575 |
font-size: 0.98rem !important;
|
576 |
font-family: 'Inter', sans-serif !important;
|
577 |
+
color: var(--text-primary) !important; /* Ensure text color in inputs */
|
578 |
transition: border-color 0.2s ease, box-shadow 0.2s ease !important;
|
579 |
box-shadow: var(--shadow-sm) !important;
|
580 |
}}
|
|
|
902 |
}}
|
903 |
"""
|
904 |
|
905 |
+
# Removed theme_mode="light" to avoid TypeError
|
906 |
+
with gr.Blocks(css=custom_css, title="Landlord-Tenant Rights Assistant") as demo:
|
|
|
907 |
with gr.Group(elem_classes="app-header-wrapper"):
|
908 |
gr.Markdown(
|
909 |
"""
|