markytools commited on
Commit
2f04502
·
1 Parent(s): 21dfa70

beautified the UI

Browse files
Files changed (2) hide show
  1. .gitignore +4 -1
  2. app.py +239 -29
.gitignore CHANGED
@@ -6,4 +6,7 @@ app_local.py
6
  ecommerce_duckdb.ipynb
7
  openrouter_testings.ipynb
8
  appBackup.py
9
- prompt_instructions.txt
 
 
 
 
6
  ecommerce_duckdb.ipynb
7
  openrouter_testings.ipynb
8
  appBackup.py
9
+ prompt_instructions.txt
10
+ app_localBackup.py
11
+ streamlit_app.log
12
+ streamlit_app_8502.log
app.py CHANGED
@@ -1,6 +1,9 @@
1
  import streamlit as st
2
  from tempfile import NamedTemporaryFile
3
 
 
 
 
4
  import pprint
5
  import re
6
  import os
@@ -26,16 +29,6 @@ if not OPEN_ROUTER_KEY:
26
  st.warning("Please enter your OpenRouter API Key to proceed.")
27
  st.stop()
28
 
29
- try:
30
- pswdVal = st.experimental_get_query_params()['pwd'][0]
31
- if pswdVal==st.secrets["PSWD"]:
32
- isPswdValid = True
33
- except:
34
- pass
35
-
36
- if not isPswdValid:
37
- st.write("Invalid Password")
38
-
39
  def call_openrouter(content: str) -> str:
40
  """Send a chat request to OpenRouter and return a safe string response."""
41
  try:
@@ -302,43 +295,241 @@ radioButtonList = ["E-commerce CSV (https://www.kaggle.com/datasets/mervemenekse
302
  f"URL Chat with Google's Latest Earnings ({defaultGoogleURL})",
303
  "Enter my own URL"]
304
 
305
- # Add some designs to the radio buttons
306
  st.markdown("""
307
  <style>
308
- .stRadio {
309
- padding: 10px;
310
- border-radius: 5px;
311
- background-color: #f5f5f5;
 
 
 
 
 
 
 
 
 
 
 
 
312
  }
313
 
314
- .stRadio input[type="radio"] {
 
 
 
 
 
 
 
 
 
 
 
315
  position: absolute;
316
- opacity: 0;
317
- cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
318
  }
319
 
320
- .stRadio label {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  display: flex;
322
- justify-content: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  align-items: center;
324
- cursor: pointer;
325
- font-size: 16px;
326
- color: #333;
 
 
 
327
  }
328
 
329
- .stRadio label:hover {
330
- color: #000;
 
 
331
  }
332
 
333
- .stRadio.st-selected input[type="radio"] ~ label {
334
- color: #000;
335
- background-color: #d9d9d9;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
  }
337
  </style>
338
  """, unsafe_allow_html=True)
339
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  genre = st.radio(
341
- "Tired of reading your files? Chat with it using AI! Choose dataset to finetune", radioButtonList, index=0
342
  )
343
 
344
  pdfCSVURLText = ""
@@ -377,6 +568,19 @@ else: # Default, E-commerce CSV
377
  )
378
  st.info(f"{DEFAULT_ECOMMERCE_CSV} not found. Using an inline sample instead. Upload your own CSV if you need the full dataset.")
379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  isCustomURL = genre==radioButtonList[4]
381
  urlInput = st.text_input('Enter your own URL', '', placeholder=f"Type your URL here (e.g. {defaultGoogleURL})", disabled=not isCustomURL)
382
 
@@ -414,6 +618,12 @@ elif genre==radioButtonList[4]: # Custom URL
414
  else: # E-commerce CSV
415
  enableChatBox = True
416
 
 
 
 
 
 
 
417
  chatTextStr = st.text_input(f'Ask me anything about this {pdfCSVURLText}', '', placeholder=f"Type here (e.g. {exampleQuestion})", disabled=not enableChatBox)
418
  chatWithPDFButton = "CLICK HERE TO START CHATTING"
419
  if st.button(chatWithPDFButton, disabled=not enableChatBox and not chatTextStr): # Button Cliked
 
1
  import streamlit as st
2
  from tempfile import NamedTemporaryFile
3
 
4
+ # Page-level look and feel
5
+ st.set_page_config(page_title="Document & Data Copilot", page_icon="💬", layout="wide")
6
+
7
  import pprint
8
  import re
9
  import os
 
29
  st.warning("Please enter your OpenRouter API Key to proceed.")
30
  st.stop()
31
 
 
 
 
 
 
 
 
 
 
 
32
  def call_openrouter(content: str) -> str:
33
  """Send a chat request to OpenRouter and return a safe string response."""
34
  try:
 
295
  f"URL Chat with Google's Latest Earnings ({defaultGoogleURL})",
296
  "Enter my own URL"]
297
 
298
+ # Visual polish
299
  st.markdown("""
300
  <style>
301
+ @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&display=swap');
302
+
303
+ html, body, [class*="css"] {
304
+ font-family: 'Space Grotesk', system-ui, -apple-system, sans-serif;
305
+ }
306
+
307
+ .stApp {
308
+ background: radial-gradient(circle at 20% 20%, #e2f2ff 0, #f8fafc 50%, #ffffff 100%);
309
+ color: #0f172a;
310
+ }
311
+
312
+ .block-container {
313
+ padding-top: 1.5rem;
314
+ padding-bottom: 3rem;
315
+ padding-left: 2.5rem;
316
+ padding-right: 2.5rem;
317
  }
318
 
319
+ .hero {
320
+ position: relative;
321
+ overflow: hidden;
322
+ padding: 1.5rem 1.8rem;
323
+ border-radius: 18px;
324
+ border: 1px solid #e5e7eb;
325
+ background: linear-gradient(135deg, rgba(59,130,246,0.12), rgba(16,185,129,0.08));
326
+ box-shadow: 0 18px 45px rgba(15, 23, 42, 0.12);
327
+ }
328
+
329
+ .hero:before {
330
+ content: "";
331
  position: absolute;
332
+ right: -120px;
333
+ top: -80px;
334
+ width: 260px;
335
+ height: 260px;
336
+ background: radial-gradient(circle, rgba(59,130,246,0.15), transparent 55%);
337
+ filter: blur(6px);
338
+ }
339
+
340
+ .hero h1 {
341
+ margin: 0.15rem 0 0.35rem 0;
342
+ font-size: 2rem;
343
+ line-height: 1.2;
344
+ letter-spacing: -0.02em;
345
+ color: #0f172a;
346
  }
347
 
348
+ .hero p {
349
+ color: #0f172a;
350
+ opacity: 0.9;
351
+ }
352
+
353
+ .eyebrow {
354
+ text-transform: uppercase;
355
+ letter-spacing: 0.14em;
356
+ font-size: 0.75rem;
357
+ font-weight: 700;
358
+ color: #0ea5e9;
359
+ margin: 0;
360
+ }
361
+
362
+ .pill-row {
363
  display: flex;
364
+ gap: 0.5rem;
365
+ flex-wrap: wrap;
366
+ margin-top: 0.85rem;
367
+ }
368
+
369
+ .pill {
370
+ padding: 0.35rem 0.65rem;
371
+ border-radius: 10px;
372
+ background: rgba(15, 23, 42, 0.08);
373
+ font-size: 0.85rem;
374
+ font-weight: 600;
375
+ }
376
+
377
+ .section-label {
378
+ font-size: 0.85rem;
379
+ letter-spacing: 0.06em;
380
+ text-transform: uppercase;
381
+ color: #475569;
382
+ margin-bottom: 0.2rem;
383
+ font-weight: 700;
384
+ }
385
+
386
+ .section-card {
387
+ background: #ffffff;
388
+ border: 1px solid #e5e7eb;
389
+ border-radius: 16px;
390
+ padding: 1.1rem 1.2rem;
391
+ box-shadow: 0 12px 32px rgba(15, 23, 42, 0.08);
392
+ }
393
+
394
+ .section-card.compact {
395
+ padding: 0.9rem 1rem;
396
+ margin-top: 0.5rem;
397
+ }
398
+
399
+ .prompt-chip {
400
+ display: inline-flex;
401
+ align-items: center;
402
+ gap: 0.35rem;
403
+ padding: 0.5rem 0.75rem;
404
+ border-radius: 12px;
405
+ background: #0ea5e911;
406
+ border: 1px solid #bae6fd;
407
+ color: #0f172a;
408
+ font-weight: 600;
409
+ }
410
+
411
+ .status-pill {
412
+ display: inline-flex;
413
  align-items: center;
414
+ gap: 0.35rem;
415
+ padding: 0.45rem 0.7rem;
416
+ border-radius: 999px;
417
+ border: 1px solid #e2e8f0;
418
+ font-weight: 600;
419
+ font-size: 0.9rem;
420
  }
421
 
422
+ .status-pill.ready {
423
+ background: #ecfeff;
424
+ border-color: #a5f3fc;
425
+ color: #0f172a;
426
  }
427
 
428
+ .status-pill.idle {
429
+ background: #f8fafc;
430
+ border-color: #e2e8f0;
431
+ color: #475569;
432
+ }
433
+
434
+ .stRadio div[role="radiogroup"] {
435
+ display: grid;
436
+ gap: 0.4rem;
437
+ }
438
+
439
+ .stRadio div[role="radio"] {
440
+ border: 1px solid #e2e8f0;
441
+ padding: 0.85rem 1rem;
442
+ border-radius: 12px;
443
+ background: #f8fafc;
444
+ transition: all 0.18s ease-in-out;
445
+ box-shadow: 0 8px 22px rgba(15, 23, 42, 0.05);
446
+ }
447
+
448
+ .stRadio div[role="radio"][aria-checked="true"] {
449
+ border-color: #2563eb;
450
+ background: #ffffff;
451
+ box-shadow: 0 18px 40px rgba(37, 99, 235, 0.15);
452
+ }
453
+
454
+ .stRadio div[role="radio"]:hover {
455
+ border-color: #3b82f6;
456
+ transform: translateY(-1px);
457
+ }
458
+
459
+ .stTextInput>div>div>input {
460
+ border-radius: 12px;
461
+ border: 1px solid #e2e8f0;
462
+ background: #ffffff;
463
+ padding: 0.75rem 0.85rem;
464
+ }
465
+
466
+ .stTextInput>div>div>input:focus {
467
+ border-color: #2563eb;
468
+ box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
469
+ }
470
+
471
+ .stFileUploader {
472
+ border-radius: 14px;
473
+ border: 1px dashed #cbd5e1;
474
+ padding: 0.4rem 0.75rem 0.75rem 0.75rem;
475
+ background: #f8fafc;
476
+ }
477
+
478
+ .stButton>button {
479
+ background: linear-gradient(135deg, #2563eb, #0ea5e9);
480
+ color: #ffffff;
481
+ border: none;
482
+ padding: 0.75rem 1.35rem;
483
+ border-radius: 12px;
484
+ font-weight: 700;
485
+ letter-spacing: 0.02em;
486
+ box-shadow: 0 12px 30px rgba(14, 165, 233, 0.28);
487
+ transition: transform 0.12s ease, box-shadow 0.12s ease;
488
+ }
489
+
490
+ .stButton>button:hover {
491
+ transform: translateY(-1px);
492
+ box-shadow: 0 16px 38px rgba(37, 99, 235, 0.32);
493
+ }
494
+
495
+ .stButton>button:active {
496
+ transform: translateY(0);
497
+ }
498
+
499
+ .stButton>button:disabled {
500
+ background: #e2e8f0;
501
+ color: #94a3b8;
502
+ box-shadow: none;
503
  }
504
  </style>
505
  """, unsafe_allow_html=True)
506
 
507
+ st.markdown("""
508
+ <div class="hero">
509
+ <p class="eyebrow">Document & Data Copilot</p>
510
+ <h1>Chat with your PDFs, spreadsheets, or live web pages.</h1>
511
+ <p>Upload or pick a preset, ask a focused question, and get a clear answer without digging through the source yourself.</p>
512
+ <div class="pill-row">
513
+ <span class="pill">Summaries</span>
514
+ <span class="pill">Follow-up questions</span>
515
+ <span class="pill">Trends & metrics</span>
516
+ <span class="pill">Plain-language insights</span>
517
+ </div>
518
+ </div>
519
+ """, unsafe_allow_html=True)
520
+
521
+ info_left, info_right = st.columns([1.05, 1])
522
+ with info_left:
523
+ st.markdown("#### What you can do")
524
+ st.markdown("- Skim long PDFs in a few bullet points\n- Ask for top performers or outliers in CSVs\n- Pull key quotes or facts from a URL\n- Iterate with follow-up questions to refine")
525
+
526
+ with info_right:
527
+ st.markdown("#### Quick tips")
528
+ st.markdown("- Keep prompts short and specific\n- Mention the format you want (bullets, table, headline)\n- Ask one question at a time for best results\n- You can chain questions; context is remembered")
529
+
530
+ st.markdown("### Choose a source to explore")
531
  genre = st.radio(
532
+ "Pick the content you want to chat with", radioButtonList, index=0, key="source_radio"
533
  )
534
 
535
  pdfCSVURLText = ""
 
568
  )
569
  st.info(f"{DEFAULT_ECOMMERCE_CSV} not found. Using an inline sample instead. Upload your own CSV if you need the full dataset.")
570
 
571
+ st.markdown("### Add your data")
572
+ st.caption("Upload a CSV/PDF or paste a URL. The built-in e-commerce sample is ready immediately.")
573
+ if exampleQuestion:
574
+ st.markdown(
575
+ f"""
576
+ <div class="section-card compact">
577
+ <div class="section-label">Suggested prompt</div>
578
+ <div class="prompt-chip">{exampleQuestion}</div>
579
+ </div>
580
+ """,
581
+ unsafe_allow_html=True,
582
+ )
583
+
584
  isCustomURL = genre==radioButtonList[4]
585
  urlInput = st.text_input('Enter your own URL', '', placeholder=f"Type your URL here (e.g. {defaultGoogleURL})", disabled=not isCustomURL)
586
 
 
618
  else: # E-commerce CSV
619
  enableChatBox = True
620
 
621
+ status_class = "ready" if enableChatBox else "idle"
622
+ status_text = "Ready to chat" if enableChatBox else "Load a file or URL to start"
623
+ st.markdown(f'<div class="status-pill {status_class}">{status_text}</div>', unsafe_allow_html=True)
624
+
625
+ st.markdown("### Ask a question")
626
+ st.caption("Short, specific prompts work best. You can ask follow-ups without reloading.")
627
  chatTextStr = st.text_input(f'Ask me anything about this {pdfCSVURLText}', '', placeholder=f"Type here (e.g. {exampleQuestion})", disabled=not enableChatBox)
628
  chatWithPDFButton = "CLICK HERE TO START CHATTING"
629
  if st.button(chatWithPDFButton, disabled=not enableChatBox and not chatTextStr): # Button Cliked