André Oliveira
refactor: document upload allows FileData
94a9110
raw
history blame
5.09 kB
import gradio as gr
import requests
import json
import os
import shutil
import threading
import mimetypes
from models import OptimizeRequest, AutotuneRequest, QARequest
from api import start_api
threading.Thread(target=start_api, daemon=True).start()
# Base URL for internal calls
BASE_INTERNAL = "http://127.0.0.1:8000"
def call_api(endpoint: str, payload: dict) -> str:
try:
r = requests.post(f"{BASE_INTERNAL}{endpoint}", json=payload, timeout=120)
return json.dumps(r.json(), indent=2)
except Exception as e:
return str(e)
def upload_docs_tool(files, docs_path="data/docs"):
"""
Upload documents to the server's docs folder.
Accepts local file paths or URLs. Returns a list of MCP FileData-like dicts.
"""
os.makedirs(docs_path, exist_ok=True)
saved = []
for f in files:
if f.startswith("http://") or f.startswith("https://"):
# Download file from URL
r = requests.get(f, stream=True)
fname = f.split("/")[-1]
dest = os.path.join(docs_path, fname)
with open(dest, "wb") as out_file:
shutil.copyfileobj(r.raw, out_file)
else:
# Local file path
fname = os.path.basename(f)
dest = os.path.join(docs_path, fname)
shutil.copy(f, dest)
mime_type = mimetypes.guess_type(dest)[0] or "application/octet-stream"
saved.append({
"path": dest,
"url": f"file://{os.path.abspath(dest)}",
"orig_name": fname,
"mime_type": mime_type,
"is_stream": False,
"meta": {}
})
return {"status": "ok", "uploaded_files": saved, "docs_path": docs_path}
def optimize_rag_tool(payload: str) -> str:
"""🔧 Explicit optimization request: user provides all pipeline configs manually."""
return call_api("/optimize_rag", json.loads(payload))
def autotune_tool(payload: str) -> str:
"""🔧 Autotune RAG: recommends chunk sizes and embedding models automatically."""
return call_api("/autotune_rag", json.loads(payload))
def generate_qa_tool(payload: str) -> str:
"""🧩 Generates a validation QA dataset for RAG evaluation."""
return call_api("/generate_validation_qa", json.loads(payload))
# Dynamically assign Pydantic model docstrings to MCP tool functions
optimize_rag_tool.__doc__ = OptimizeRequest.__doc__
autotune_tool.__doc__ = AutotuneRequest.__doc__
generate_qa_tool.__doc__ = QARequest.__doc__
def model_to_json(model_cls) -> str:
return json.dumps({k: v.default for k, v in model_cls.__fields__.items()}, indent=2)
# Default inputs
DEFAULT_UPLOAD_PATH = "data/docs"
DEFAULT_OPTIMIZE_JSON = model_to_json(OptimizeRequest)
DEFAULT_AUTOTUNE_JSON = model_to_json(AutotuneRequest)
DEFAULT_QA_JSON = model_to_json(QARequest)
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("# Ragmint MCP Client")
# Upload Documents
with gr.Column():
gr.Markdown("## Upload Documents")
gr.Markdown("📂 Upload files (local paths or URLs) to your `data/docs` folder")
upload_files = gr.File(file_count="multiple", type="filepath")
upload_path = gr.Textbox(value=DEFAULT_UPLOAD_PATH, label="Docs Path")
upload_btn = gr.Button("Upload", variant="primary")
upload_out = gr.JSON(label="Response")
upload_btn.click(upload_docs_tool, inputs=[upload_files, upload_path], outputs=upload_out)
gr.Markdown("---")
# Optimize RAG
with gr.Column():
gr.Markdown("## Optimize RAG")
gr.Markdown(OptimizeRequest.__doc__ or "No description available.")
optimize_input = gr.Textbox(lines=12, value=DEFAULT_OPTIMIZE_JSON, label="OptimizeRequest JSON")
optimize_btn = gr.Button("Submit", variant="primary")
optimize_out = gr.Textbox(lines=15, label="Response")
optimize_btn.click(optimize_rag_tool, inputs=optimize_input, outputs=optimize_out)
gr.Markdown("---")
# Autotune RAG
with gr.Column():
gr.Markdown("## Autotune RAG")
gr.Markdown(AutotuneRequest.__doc__ or "No description available.")
autotune_input = gr.Textbox(lines=12, value=DEFAULT_AUTOTUNE_JSON, label="AutotuneRequest JSON")
autotune_btn = gr.Button("Submit", variant="primary")
autotune_out = gr.Textbox(lines=15)
autotune_btn.click(autotune_tool, inputs=autotune_input, outputs=autotune_out)
gr.Markdown("---")
# Generate QA
with gr.Column():
gr.Markdown("## Generate QA")
gr.Markdown(QARequest.__doc__ or "No description available.")
qa_input = gr.Textbox(lines=12, value=DEFAULT_QA_JSON, label="QARequest JSON")
qa_btn = gr.Button("Submit", variant="primary")
qa_out = gr.Textbox(lines=15, label="Response")
qa_btn.click(generate_qa_tool, inputs=qa_input, outputs=qa_out)
gr.Markdown("---")
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
mcp_server=True,
show_error=True
)