GodRad commited on
Commit
db59efd
Β·
verified Β·
1 Parent(s): 966243e

Upload 8 files

Browse files
Files changed (3) hide show
  1. .streamlit/config.toml +19 -0
  2. Dockerfile +5 -0
  3. app.py +110 -4
.streamlit/config.toml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [server]
2
+ headless = true
3
+ port = 7860
4
+ enableCORS = false
5
+ enableXsrfProtection = false
6
+
7
+ [browser]
8
+ gatherUsageStats = false
9
+ serverAddress = "0.0.0.0"
10
+
11
+ [theme]
12
+ primaryColor = "#1f6feb"
13
+ backgroundColor = "#0e1117"
14
+ secondaryBackgroundColor = "#161b22"
15
+ textColor = "#ffffff"
16
+
17
+ [client]
18
+ showErrorDetails = false
19
+ toolbarMode = "minimal"
Dockerfile CHANGED
@@ -6,6 +6,11 @@ ENV PYTHONUNBUFFERED=1 \
6
  PORT=7860 \
7
  HOME=/home/user
8
 
 
 
 
 
 
9
  # Create user for HF Spaces (UID 1000 required)
10
  RUN useradd -m -u 1000 user
11
 
 
6
  PORT=7860 \
7
  HOME=/home/user
8
 
9
+ # Install system dependencies
10
+ RUN apt-get update && apt-get install -y \
11
+ curl \
12
+ && rm -rf /var/lib/apt/lists/*
13
+
14
  # Create user for HF Spaces (UID 1000 required)
15
  RUN useradd -m -u 1000 user
16
 
app.py CHANGED
@@ -28,6 +28,9 @@ st.markdown("""
28
  .source-file {background-color: #1f6feb; color: white;}
29
  .source-web {background-color: #238636; color: white;}
30
  .source-youtube {background-color: #da3633; color: white;}
 
 
 
31
  </style>
32
  """, unsafe_allow_html=True)
33
 
@@ -147,7 +150,7 @@ else:
147
  st.title(f"πŸ” RAG SaaS Platform")
148
 
149
  # Main tabs
150
- tab1, tab2, tab3, tab4 = st.tabs(["πŸ’¬ Ask Questions", "πŸ“ Manage Sources", "πŸ“Š Metrics", "ℹ️ About"])
151
 
152
  # Tab 1: Ask Questions
153
  with tab1:
@@ -466,8 +469,110 @@ else:
466
  except Exception as e:
467
  st.error(f"Error loading sources: {e}")
468
 
469
- # Tab 3: Metrics
470
  with tab3:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
471
  st.header("πŸ“Š Your Metrics")
472
 
473
  # Time range selector
@@ -538,14 +643,15 @@ else:
538
  except Exception as e:
539
  st.warning(f"Cache stats unavailable: {e}")
540
 
541
- # Tab 4: About
542
- with tab4:
543
  st.header("ℹ️ About RAG SaaS Platform")
544
 
545
  st.markdown("""
546
  ### Features
547
 
548
  βœ… **Multi-Source Retrieval** - Unified search across documents, URLs, and YouTube videos
 
549
  βœ… **Tenant Isolation** - Complete data and metrics separation per tenant
550
  βœ… **Optimized Performance** - Model caching with 70-90% latency reduction
551
  βœ… **Compliant YouTube** - Captions-first with transcript upload fallback
 
28
  .source-file {background-color: #1f6feb; color: white;}
29
  .source-web {background-color: #238636; color: white;}
30
  .source-youtube {background-color: #da3633; color: white;}
31
+ .source-gdrive {background-color: #34a853; color: white;}
32
+ .source-onedrive {background-color: #0078d4; color: white;}
33
+ .source-dropbox {background-color: #0061ff; color: white;}
34
  </style>
35
  """, unsafe_allow_html=True)
36
 
 
150
  st.title(f"πŸ” RAG SaaS Platform")
151
 
152
  # Main tabs
153
+ tab1, tab2, tab3, tab4, tab5 = st.tabs(["πŸ’¬ Ask Questions", "πŸ“ Manage Sources", "☁️ Cloud Connectors", "πŸ“Š Metrics", "ℹ️ About"])
154
 
155
  # Tab 1: Ask Questions
156
  with tab1:
 
469
  except Exception as e:
470
  st.error(f"Error loading sources: {e}")
471
 
472
+ # Tab 3: Cloud Connectors
473
  with tab3:
474
+ st.header("☁️ Cloud Connectors")
475
+ st.write("Connect to your enterprise cloud storage to sync documents directly.")
476
+
477
+ # Connect New Account
478
+ st.subheader("Connect New Account")
479
+ col1, col2, col3 = st.columns(3)
480
+
481
+ with col1:
482
+ if st.button("πŸ”Œ Connect Google Drive", use_container_width=True):
483
+ try:
484
+ res = requests.get(f"{api_url}/v1/connectors/gdrive/oauth/start?tenant_id={st.session_state.tenant_id}")
485
+ if res.status_code == 200:
486
+ st.markdown(f"[Click here to authorize Google Drive]({res.json()['auth_url']})")
487
+ else:
488
+ st.error("Failed to start GDrive OAuth")
489
+ except Exception as e:
490
+ st.error(f"Error: {e}")
491
+
492
+ with col2:
493
+ if st.button("πŸ”Œ Connect OneDrive", use_container_width=True):
494
+ try:
495
+ res = requests.get(f"{api_url}/v1/connectors/onedrive/oauth/start?tenant_id={st.session_state.tenant_id}")
496
+ if res.status_code == 200:
497
+ st.markdown(f"[Click here to authorize OneDrive]({res.json()['auth_url']})")
498
+ else:
499
+ st.error("Failed to start OneDrive OAuth")
500
+ except Exception as e:
501
+ st.error(f"Error: {e}")
502
+
503
+ with col3:
504
+ if st.button("πŸ”Œ Connect Dropbox", use_container_width=True):
505
+ try:
506
+ res = requests.get(f"{api_url}/v1/connectors/dropbox/oauth/start?tenant_id={st.session_state.tenant_id}")
507
+ if res.status_code == 200:
508
+ st.markdown(f"[Click here to authorize Dropbox]({res.json()['auth_url']})")
509
+ else:
510
+ st.error("Failed to start Dropbox OAuth")
511
+ except Exception as e:
512
+ st.error(f"Error: {e}")
513
+
514
+ st.divider()
515
+
516
+ # Manage Existing Connectors
517
+ st.subheader("Your Connected Accounts")
518
+ try:
519
+ response = requests.get(
520
+ f"{api_url}/v1/connectors/",
521
+ params={"tenant_id": st.session_state.tenant_id}
522
+ )
523
+ if response.status_code == 200:
524
+ connectors = response.json()
525
+ if connectors:
526
+ for conn in connectors:
527
+ with st.expander(f"{conn['provider'].upper()} - {conn['display_name']}"):
528
+ col_a, col_b, col_c = st.columns([2, 1, 1])
529
+ with col_a:
530
+ st.write(f"**Status:** {conn['sync_status'].upper()}")
531
+ if conn['last_sync']:
532
+ st.write(f"**Last Sync:** {conn['last_sync']}")
533
+
534
+ with col_b:
535
+ if st.button("πŸ”„ Trigger Sync", key=f"sync_{conn['id']}"):
536
+ sync_res = requests.post(f"{api_url}/v1/connectors/{conn['id']}/sync")
537
+ if sync_res.status_code == 200:
538
+ st.success("Sync triggered!")
539
+ else:
540
+ st.error("Failed to trigger sync")
541
+
542
+ with col_c:
543
+ if st.button("πŸ“ Manage Targets", key=f"targets_{conn['id']}"):
544
+ st.session_state[f"show_targets_{conn['id']}"] = True
545
+
546
+ # Target Selection Mock/Simplified
547
+ if st.session_state.get(f"show_targets_{conn['id']}"):
548
+ st.info("Loading roots...")
549
+ roots_res = requests.get(f"{api_url}/v1/connectors/{conn['id']}/roots")
550
+ if roots_res.status_code == 200:
551
+ roots = roots_res.json()
552
+ target_ids = st.multiselect(
553
+ "Select Folders/Drives to sync",
554
+ options=[r['id'] for r in roots],
555
+ format_func=lambda x: next(r['name'] for r in roots if r['id'] == x),
556
+ key=f"ms_{conn['id']}"
557
+ )
558
+ if st.button("Save Targets", key=f"save_{conn['id']}"):
559
+ selected_targets = [{"id": tid, "type": "folder"} for tid in target_ids]
560
+ save_res = requests.post(
561
+ f"{api_url}/v1/connectors/{conn['id']}/targets",
562
+ params={"tenant_id": st.session_state.tenant_id},
563
+ json=selected_targets
564
+ )
565
+ if save_res.status_code == 200:
566
+ st.success("Targets updated!")
567
+ st.session_state[f"show_targets_{conn['id']}"] = False
568
+ st.rerun()
569
+ else:
570
+ st.info("No cloud accounts connected yet.")
571
+ except Exception as e:
572
+ st.error(f"Error fetching connectors: {e}")
573
+
574
+ # Tab 4: Metrics
575
+ with tab4:
576
  st.header("πŸ“Š Your Metrics")
577
 
578
  # Time range selector
 
643
  except Exception as e:
644
  st.warning(f"Cache stats unavailable: {e}")
645
 
646
+ # Tab 5: About
647
+ with tab5:
648
  st.header("ℹ️ About RAG SaaS Platform")
649
 
650
  st.markdown("""
651
  ### Features
652
 
653
  βœ… **Multi-Source Retrieval** - Unified search across documents, URLs, and YouTube videos
654
+ βœ… **Enterprise Cloud Connectors** - Native sync with Google Drive, OneDrive, and Dropbox
655
  βœ… **Tenant Isolation** - Complete data and metrics separation per tenant
656
  βœ… **Optimized Performance** - Model caching with 70-90% latency reduction
657
  βœ… **Compliant YouTube** - Captions-first with transcript upload fallback