Spaces:
Sleeping
Sleeping
fix
Browse files
main.py
CHANGED
|
@@ -12,6 +12,7 @@ from pathlib import Path
|
|
| 12 |
from datetime import datetime
|
| 13 |
import time
|
| 14 |
import random
|
|
|
|
| 15 |
|
| 16 |
from content_analyzer.document_parser import DocumentProcessor
|
| 17 |
from search_engine.indexer import RetrieverBuilder
|
|
@@ -19,6 +20,22 @@ from intelligence.orchestrator import AgentWorkflow
|
|
| 19 |
from configuration import definitions, parameters
|
| 20 |
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
# Example data for demo
|
| 23 |
EXAMPLES = {
|
| 24 |
"Generative AI and Jobs": {
|
|
@@ -602,12 +619,16 @@ window.addEventListener("load", tick);
|
|
| 602 |
setInterval(tick, 500);
|
| 603 |
'''
|
| 604 |
|
| 605 |
-
with
|
|
|
|
|
|
|
|
|
|
|
|
|
| 606 |
gr.Markdown("### SmartDoc AI - Document Q&A", elem_classes="app-title")
|
| 607 |
gr.Markdown("Upload your documents and ask questions. Answers will appear below, just like a chat.", elem_classes="app-description")
|
| 608 |
gr.Markdown("---")
|
| 609 |
|
| 610 |
-
# Examples dropdown
|
| 611 |
example_dropdown = gr.Dropdown(
|
| 612 |
label="Quick Start - Choose an Example",
|
| 613 |
choices=list(EXAMPLES.keys()),
|
|
@@ -635,7 +656,8 @@ setInterval(tick, 500);
|
|
| 635 |
"session_start": datetime.now().strftime("%Y-%m-%d %H:%M")
|
| 636 |
})
|
| 637 |
|
| 638 |
-
def process_question(question_text, uploaded_files, chat_history):
|
|
|
|
| 639 |
chat_history = chat_history or []
|
| 640 |
yield (
|
| 641 |
chat_history,
|
|
@@ -865,25 +887,53 @@ setInterval(tick, 500);
|
|
| 865 |
return [], "", "Select a valid example from the dropdown above"
|
| 866 |
ex_data = EXAMPLES[example_key]
|
| 867 |
question_text = ex_data["question"]
|
| 868 |
-
|
| 869 |
-
|
| 870 |
-
|
| 871 |
-
|
| 872 |
-
|
| 873 |
-
|
| 874 |
-
|
| 875 |
-
|
| 876 |
-
|
| 877 |
-
|
| 878 |
-
|
| 879 |
-
|
| 880 |
-
|
| 881 |
-
|
| 882 |
-
|
| 883 |
-
|
| 884 |
-
|
| 885 |
-
|
| 886 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 887 |
|
| 888 |
example_dropdown.change(
|
| 889 |
fn=load_example,
|
|
@@ -905,7 +955,7 @@ setInterval(tick, 500);
|
|
| 905 |
server_port = _find_open_port(configured_port)
|
| 906 |
logger.info(f"Launching Gradio on port {server_port}")
|
| 907 |
logger.info(f"Access the app at: http://127.0.0.1:{server_port}")
|
| 908 |
-
demo.launch(server_name="127.0.0.1", server_port=server_port, share=False)
|
| 909 |
|
| 910 |
|
| 911 |
if __name__ == "__main__":
|
|
|
|
| 12 |
from datetime import datetime
|
| 13 |
import time
|
| 14 |
import random
|
| 15 |
+
from collections import defaultdict, deque
|
| 16 |
|
| 17 |
from content_analyzer.document_parser import DocumentProcessor
|
| 18 |
from search_engine.indexer import RetrieverBuilder
|
|
|
|
| 20 |
from configuration import definitions, parameters
|
| 21 |
|
| 22 |
|
| 23 |
+
# Rate limiting configuration - 3 requests per 60 seconds per IP
|
| 24 |
+
WINDOW_S = 3600
|
| 25 |
+
MAX_CALLS = 3
|
| 26 |
+
_calls = defaultdict(deque) # ip -> timestamps
|
| 27 |
+
|
| 28 |
+
def rate_limit(request):
|
| 29 |
+
ip = getattr(request.client, "host", "unknown")
|
| 30 |
+
now = time.time()
|
| 31 |
+
q = _calls[ip]
|
| 32 |
+
while q and (now - q[0]) > WINDOW_S:
|
| 33 |
+
q.popleft()
|
| 34 |
+
if len(q) >= MAX_CALLS:
|
| 35 |
+
raise gr.Error(f"Rate limit: {MAX_CALLS} requests per {WINDOW_S}s. Please wait.")
|
| 36 |
+
q.append(now)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
# Example data for demo
|
| 40 |
EXAMPLES = {
|
| 41 |
"Generative AI and Jobs": {
|
|
|
|
| 619 |
setInterval(tick, 500);
|
| 620 |
'''
|
| 621 |
|
| 622 |
+
# Launch server - Compatible with both local and Hugging Face Spaces
|
| 623 |
+
# HF Spaces sets SPACE_ID environment variable
|
| 624 |
+
is_hf_space = os.environ.get("SPACE_ID") is not None
|
| 625 |
+
|
| 626 |
+
with gr.Blocks(title="SmartDoc AI") as demo:
|
| 627 |
gr.Markdown("### SmartDoc AI - Document Q&A", elem_classes="app-title")
|
| 628 |
gr.Markdown("Upload your documents and ask questions. Answers will appear below, just like a chat.", elem_classes="app-description")
|
| 629 |
gr.Markdown("---")
|
| 630 |
|
| 631 |
+
# Examples dropdown - visible for both local and HF Spaces
|
| 632 |
example_dropdown = gr.Dropdown(
|
| 633 |
label="Quick Start - Choose an Example",
|
| 634 |
choices=list(EXAMPLES.keys()),
|
|
|
|
| 656 |
"session_start": datetime.now().strftime("%Y-%m-%d %H:%M")
|
| 657 |
})
|
| 658 |
|
| 659 |
+
def process_question(question_text, uploaded_files, chat_history, request: gr.Request):
|
| 660 |
+
rate_limit(request)
|
| 661 |
chat_history = chat_history or []
|
| 662 |
yield (
|
| 663 |
chat_history,
|
|
|
|
| 887 |
return [], "", "Select a valid example from the dropdown above"
|
| 888 |
ex_data = EXAMPLES[example_key]
|
| 889 |
question_text = ex_data["question"]
|
| 890 |
+
file_names = ex_data["file_paths"]
|
| 891 |
+
|
| 892 |
+
# Try to download from HF dataset if on Spaces
|
| 893 |
+
if is_hf_space:
|
| 894 |
+
try:
|
| 895 |
+
from huggingface_hub import hf_hub_download
|
| 896 |
+
copied_files = []
|
| 897 |
+
file_info_text = f"✅ Loaded: {example_key}\n\n"
|
| 898 |
+
for file_path in file_names:
|
| 899 |
+
filename = os.path.basename(file_path)
|
| 900 |
+
try:
|
| 901 |
+
local_path = hf_hub_download(
|
| 902 |
+
repo_id="TilanTAB/smartdoc-samples",
|
| 903 |
+
repo_type="dataset",
|
| 904 |
+
filename=filename,
|
| 905 |
+
)
|
| 906 |
+
copied_files.append(local_path)
|
| 907 |
+
file_size_mb = os.path.getsize(local_path) / (1024 * 1024)
|
| 908 |
+
file_info_text += f"📄 {filename} ({file_size_mb:.2f} MB)\n"
|
| 909 |
+
except Exception as e:
|
| 910 |
+
logger.error(f"Failed to download {filename}: {e}")
|
| 911 |
+
file_info_text += f"❌ {filename} - Download failed\n"
|
| 912 |
+
if not copied_files:
|
| 913 |
+
return [], "", "❌ Could not load example files from dataset"
|
| 914 |
+
return copied_files, question_text, file_info_text
|
| 915 |
+
except ImportError:
|
| 916 |
+
return [], "", "❌ huggingface_hub not installed"
|
| 917 |
+
else:
|
| 918 |
+
# Local mode - use files from samples directory
|
| 919 |
+
import tempfile
|
| 920 |
+
temp_dir = tempfile.mkdtemp()
|
| 921 |
+
copied_files = []
|
| 922 |
+
file_info_text = f"Loaded: {example_key}\n\n"
|
| 923 |
+
for source_file_path in file_names:
|
| 924 |
+
abs_source = os.path.abspath(source_file_path)
|
| 925 |
+
if os.path.exists(abs_source):
|
| 926 |
+
filename = os.path.basename(abs_source)
|
| 927 |
+
temp_file_path = os.path.join(temp_dir, filename)
|
| 928 |
+
shutil.copy2(abs_source, temp_file_path)
|
| 929 |
+
copied_files.append(temp_file_path)
|
| 930 |
+
file_size_mb = os.path.getsize(temp_file_path) / (1024 * 1024)
|
| 931 |
+
file_info_text += f"{filename} ({file_size_mb:.2f} MB)\n"
|
| 932 |
+
else:
|
| 933 |
+
file_info_text += f"{source_file_path} not found\n"
|
| 934 |
+
if not copied_files:
|
| 935 |
+
return [], "", "Could not load example files"
|
| 936 |
+
return copied_files, question_text, file_info_text
|
| 937 |
|
| 938 |
example_dropdown.change(
|
| 939 |
fn=load_example,
|
|
|
|
| 955 |
server_port = _find_open_port(configured_port)
|
| 956 |
logger.info(f"Launching Gradio on port {server_port}")
|
| 957 |
logger.info(f"Access the app at: http://127.0.0.1:{server_port}")
|
| 958 |
+
demo.launch(theme=gr.themes.Soft(), server_name="127.0.0.1", server_port=server_port, share=False, css=css, js=js)
|
| 959 |
|
| 960 |
|
| 961 |
if __name__ == "__main__":
|