| import streamlit as st
|
| import requests
|
| import os
|
| import sys
|
| from dotenv import load_dotenv
|
|
|
|
|
| sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
| from utils import load_css
|
|
|
| load_dotenv()
|
|
|
| API_URL = os.getenv("API_URL", "http://localhost:8000/")
|
|
|
| st.set_page_config(page_title="Documents", page_icon="π", layout="wide")
|
| load_css()
|
|
|
| st.markdown('<h1 class="gradient-text">π Document Management</h1>', unsafe_allow_html=True)
|
|
|
| def fetch_documents():
|
| try:
|
| res = requests.get(API_URL + "documents")
|
| if res.status_code == 200:
|
| return res.json().get("documents", [])
|
| except Exception:
|
| st.error("Failed to fetch documents from the server.")
|
| return []
|
|
|
| def upload_document(file):
|
| files = {"file": (file.name, file.getvalue(), file.type)}
|
| try:
|
| res=requests.post(API_URL + "document", files=files)
|
| except requests.exceptions.RequestException:
|
| st.error("β οΈ Could not connect to the backend. Please try again later.")
|
| return None
|
| return res
|
|
|
| def delete_document(name):
|
| try:
|
| res=requests.delete(API_URL + f"document", json={"source": name})
|
| except requests.exceptions.RequestException:
|
| st.error("β οΈ Could not connect to the backend. Please try again later.")
|
| return None
|
| return res
|
|
|
|
|
| st.subheader("π€ Upload Document")
|
| st.markdown("""
|
| <div style="background: rgba(255, 255, 255, 0.05); padding: 20px; border-radius: 12px; border: 1px dashed rgba(255, 255, 255, 0.2); margin-bottom: 20px;">
|
| <p style="margin: 0; color: #aaa;">Supported formats: PDF, DOCX, TXT</p>
|
| </div>
|
| """, unsafe_allow_html=True)
|
|
|
| uploaded_file = st.file_uploader(
|
| "Choose a file",
|
| type=["pdf", "docx", "txt"],
|
| label_visibility="collapsed"
|
| )
|
|
|
| if uploaded_file:
|
| if st.button("Upload and Ingest", type="primary"):
|
| with st.spinner("Uploading and ingesting document..."):
|
| res = upload_document(uploaded_file)
|
|
|
| if res is None:
|
| pass
|
| elif res.status_code == 200:
|
| st.success("β
Document uploaded successfully")
|
| else:
|
| st.error("β Failed to upload document")
|
|
|
| st.divider()
|
|
|
|
|
| st.subheader("π Available Documents")
|
|
|
| search_col, _ = st.columns([1, 1])
|
| with search_col:
|
| search_query = st.text_input(
|
| "",
|
| placeholder="π Search documents...",
|
| label_visibility="collapsed"
|
| )
|
|
|
| with st.spinner("Fetching documents..."):
|
| documents = fetch_documents()
|
|
|
| if search_query:
|
| documents = [
|
| doc for doc in documents
|
| if search_query.lower() in doc[0].lower()
|
| ]
|
|
|
| if not documents:
|
| st.info("No documents available.")
|
| else:
|
|
|
| st.markdown("""
|
| <div style="display: flex; font-weight: bold; color: #e0e0e0; padding: 10px 0; border-bottom: 2px solid rgba(67, 97, 238, 0.5); background: rgba(0,0,0,0.2); margin-bottom: 10px;">
|
| <div style="flex: 3; padding-left: 10px;">Filename</div>
|
| <div style="flex: 2;">Status</div>
|
| <div style="flex: 2;">Uploaded At</div>
|
| <div style="flex: 1; text-align: right; padding-right: 10px;">Actions</div>
|
| </div>
|
| """, unsafe_allow_html=True)
|
|
|
| for idx, doc in enumerate(documents):
|
| filename, status, timestamp, path = doc
|
|
|
| status_class = "status-ingested" if status == "ingested" else "status-pending"
|
| status_display = f"β
{status.capitalize()}" if status == "ingested" else f"β³ {status.capitalize()}"
|
|
|
| col1, col2, col3, col4 = st.columns([3, 2, 2, 1])
|
|
|
| with col1:
|
| st.markdown(f"<div style='padding-top: 5px; padding-left: 10px;'>{filename}</div>", unsafe_allow_html=True)
|
|
|
| with col2:
|
| st.markdown(f"<span class='status-badge {status_class}'>{status_display}</span>", unsafe_allow_html=True)
|
|
|
| with col3:
|
| st.markdown(f"<div style='padding-top: 5px; color: #aaa;'>{timestamp}</div>", unsafe_allow_html=True)
|
|
|
| with col4:
|
| if st.button("ποΈ", key=f"delete_{idx}", help="Delete Document"):
|
| with st.spinner("Deleting..."):
|
| res = delete_document(path)
|
| if res and res.status_code == 200:
|
| st.success(f"Deleted {filename}")
|
| st.rerun()
|
| else:
|
| st.error("Failed to delete")
|
|
|
| st.markdown("<hr style='margin: 5px 0; border-color: rgba(255,255,255,0.05);'>", unsafe_allow_html=True)
|
|
|