Spaces:
Sleeping
Sleeping
| import os | |
| # ----------------------------------------------------------------------------- | |
| # Streamlit runtime fixes | |
| # Some container environments (e.g., read-only root) may not set $HOME, causing | |
| # Streamlit to attempt writing to '/.streamlit' and fail with PermissionError. | |
| # We set fallback directories under /tmp before importing Streamlit. | |
| # ----------------------------------------------------------------------------- | |
| # Disable telemetry completely | |
| os.environ["STREAMLIT_BROWSER_GATHER_USAGE_STATS"] = "false" | |
| # Ensure writable directories for Streamlit telemetry & state | |
| os.environ.setdefault("HOME", "/tmp") | |
| os.environ.setdefault("XDG_STATE_HOME", "/tmp/.state") | |
| os.environ.setdefault("XDG_CONFIG_HOME", "/tmp/.config") | |
| os.environ.setdefault("XDG_DATA_HOME", "/tmp/.data") | |
| # Create streamlit directory to prevent permission errors | |
| os.makedirs("/tmp/.streamlit", exist_ok=True) | |
| # Monkey-patch Path.home() so that Streamlit (which calls pathlib.Path.home) | |
| # resolves to /tmp instead of the container default (/). | |
| from pathlib import Path | |
| def _tmp_home() -> Path: # type: ignore | |
| return Path("/tmp") | |
| Path.home = _tmp_home # type: ignore | |
| import streamlit as st | |
| import requests | |
| from typing import Tuple | |
| # ----------------------------- | |
| # Configuration | |
| # ----------------------------- | |
| ENDPOINT_URL = "https://n8n.flintstorage812.com/webhook/universal-ingest" | |
| # ----------------------------- | |
| # Helper Functions | |
| # ----------------------------- | |
| def send_file(file_bytes: bytes, filename: str, mime_type: str) -> Tuple[bool, dict]: | |
| """Send a file to the universal-ingest endpoint. | |
| Returns (success, response_json) | |
| """ | |
| try: | |
| files = {"file": (filename, file_bytes, mime_type)} | |
| response = requests.post(ENDPOINT_URL, files=files, timeout=60) | |
| response.raise_for_status() | |
| return True, response.json() | |
| except Exception as e: | |
| return False, {"error": str(e)} | |
| def send_url(url: str) -> Tuple[bool, dict]: | |
| """Send a website URL as JSON to the universal-ingest endpoint.""" | |
| try: | |
| headers = {"Content-Type": "application/json"} | |
| response = requests.post(ENDPOINT_URL, json={"url": url}, headers=headers, timeout=60) | |
| response.raise_for_status() | |
| return True, response.json() | |
| except Exception as e: | |
| return False, {"error": str(e)} | |
| # ----------------------------- | |
| # Local file persistence | |
| # ----------------------------- | |
| FILE_SAVE_DIR = "files" | |
| try: | |
| os.makedirs(FILE_SAVE_DIR, exist_ok=True) | |
| except Exception as e: | |
| # If creation fails, we alert via Streamlit later | |
| print(f"[warning] Could not create {FILE_SAVE_DIR}: {e}") | |
| def save_to_disk(content: bytes, filename: str) -> str: | |
| """Save uploaded content to ./files and return the absolute path.""" | |
| path = os.path.join(FILE_SAVE_DIR, filename) | |
| with open(path, "wb") as f: | |
| f.write(content) | |
| return path | |
| # ----------------------------- | |
| # Streamlit UI | |
| # ----------------------------- | |
| st.set_page_config(page_title="Universal RAG Ingestion", page_icon="🪄", layout="centered") | |
| st.title("🪄 Universal RAG Ingestion Client") | |
| st.markdown( | |
| "Upload PDF / video / audio **or** enter a website URL to start the universal ingestion workflow.\n" | |
| "All requests are sent to:** `{}`".format(ENDPOINT_URL) | |
| ) | |
| mode = st.radio( | |
| "Select input type:", | |
| ( | |
| "📄 Upload PDF", | |
| "🎬 Upload Video / Audio", | |
| "🌐 Website URL", | |
| ), | |
| horizontal=True, | |
| ) | |
| if mode.startswith("📄"): | |
| st.subheader("Upload PDF") | |
| pdf_file = st.file_uploader("Choose a PDF file", type=["pdf"]) | |
| if pdf_file is not None: | |
| if st.button("Send to Ingestion API"): | |
| with st.spinner("Uploading and processing…"): | |
| file_bytes = pdf_file.read() | |
| saved_path = save_to_disk(file_bytes, pdf_file.name) | |
| st.write(f"Saved to {saved_path}") | |
| success, resp = send_file(file_bytes, pdf_file.name, "application/pdf") | |
| if success: | |
| st.success("✅ Success! Response:") | |
| st.json(resp) | |
| else: | |
| st.error("❌ Error while sending file") | |
| st.json(resp) | |
| elif mode.startswith("🎬"): | |
| st.subheader("Upload Video / Audio") | |
| media_file = st.file_uploader("Choose a media file", type=["mp4", "mov", "avi", "wav", "mp3", "m4a"]) | |
| if media_file is not None: | |
| if st.button("Send to Ingestion API"): | |
| with st.spinner("Uploading and processing…"): | |
| bytes_data = media_file.read() | |
| saved_path = save_to_disk(bytes_data, media_file.name) | |
| st.write(f"Saved to {saved_path}") | |
| mime_type = "video/mp4" # Fallback; Streamlit doesn't expose MIME. n8n relies on filename extension. | |
| success, resp = send_file(bytes_data, media_file.name, mime_type) | |
| if success: | |
| st.success("✅ Success! Response:") | |
| st.json(resp) | |
| else: | |
| st.error("❌ Error while sending file") | |
| st.json(resp) | |
| else: # Website URL | |
| st.subheader("Submit Website URL") | |
| url_input = st.text_input("Enter full URL (including https://)") | |
| if st.button("Send to Ingestion API") and url_input: | |
| with st.spinner("Submitting URL …"): | |
| success, resp = send_url(url_input) | |
| if success: | |
| st.success("✅ Success! Response:") | |
| st.json(resp) | |
| else: | |
| st.error("❌ Error while submitting URL") | |
| st.json(resp) | |
| st.caption("Built with Streamlit · © 2025") |