André Oliveira commited on
Commit
434392c
·
1 Parent(s): ec21b79

refactor: http not working

Browse files
Files changed (3) hide show
  1. api.py +35 -90
  2. app.py +42 -76
  3. server.py +0 -7
api.py CHANGED
@@ -1,14 +1,14 @@
 
1
  from __future__ import annotations
2
  import os
3
  import json
4
  import logging
5
  import time
 
6
 
7
  from models import OptimizeRequest, QARequest, AutotuneRequest
8
  from fastapi import FastAPI, HTTPException, UploadFile, File, Form
9
  from fastapi.middleware.cors import CORSMiddleware
10
- import uvicorn
11
- import shutil
12
 
13
  try:
14
  from ragmint.autotuner import AutoRAGTuner
@@ -33,7 +33,7 @@ load_dotenv()
33
  logging.basicConfig(level=logging.INFO)
34
  logger = logging.getLogger("ragmint_mcp_server")
35
 
36
- # FastAPI
37
  app = FastAPI(title="Ragmint MCP Server", version="0.1.0")
38
  app.add_middleware(
39
  CORSMiddleware,
@@ -43,10 +43,13 @@ app.add_middleware(
43
  allow_headers=["*"],
44
  )
45
 
46
- DEFAULT_DATA_DIR = "../data/docs"
 
47
  LEADERBOARD_STORAGE = "experiments/leaderboard.jsonl"
48
- os.makedirs("../experiments", exist_ok=True)
49
 
 
 
 
50
 
51
  @app.get("/health")
52
  def health():
@@ -56,39 +59,31 @@ def health():
56
  "import_error": str(_import_error) if _import_error else None,
57
  }
58
 
59
-
60
  @app.post("/upload_docs")
61
  async def upload_docs(
62
- docs_path: str = Form(...), # User specifies folder
63
  files: list[UploadFile] = File(...)
64
  ):
65
- os.makedirs(docs_path, exist_ok=True) # create folder if missing
66
  saved_files = []
67
-
68
  for file in files:
69
  file_path = os.path.join(docs_path, file.filename)
70
  with open(file_path, "wb") as f:
71
  shutil.copyfileobj(file.file, f)
72
  saved_files.append(file.filename)
73
-
74
  return {"status": "ok", "uploaded_files": saved_files, "docs_path": docs_path}
75
 
76
  @app.post("/optimize_rag")
77
  def optimize_rag(req: OptimizeRequest):
78
  logger.info("Received optimize_rag request: %s", req.json())
79
-
80
  if RAGMint is None:
81
- raise HTTPException(
82
- status_code=500,
83
- detail=f"Ragmint imports failed or RAGMint unavailable: {_import_error}"
84
- )
85
 
86
  docs_path = req.docs_path or DEFAULT_DATA_DIR
87
  if not os.path.isdir(docs_path):
88
  raise HTTPException(status_code=400, detail=f"docs_path does not exist: {docs_path}")
89
 
90
  try:
91
- # Build RAGMint exactly from request
92
  rag = RAGMint(
93
  docs_path=docs_path,
94
  retrievers=req.retriever,
@@ -99,12 +94,11 @@ def optimize_rag(req: OptimizeRequest):
99
  strategies=req.strategy,
100
  )
101
 
102
- # Validation selection
103
  validation_set = None
104
  validation_choice = (req.validation_choice or "").strip()
105
  default_val_path = os.path.join(docs_path, "validation_qa.json")
106
 
107
- # Auto
108
  if not validation_choice:
109
  if os.path.exists(default_val_path):
110
  validation_set = default_val_path
@@ -112,33 +106,22 @@ def optimize_rag(req: OptimizeRequest):
112
  else:
113
  logger.warning("No validation_choice provided and no default found.")
114
  validation_set = None
115
-
116
- # Remote HF dataset
117
  elif "/" in validation_choice and not os.path.exists(validation_choice):
118
  validation_set = validation_choice
119
- logger.info("Using Hugging Face validation dataset: %s", validation_set)
120
-
121
- # Local file
122
  elif os.path.exists(validation_choice):
123
  validation_set = validation_choice
124
  logger.info("Using local validation dataset: %s", validation_set)
125
-
126
- # Generate
127
  elif validation_choice.lower() == "generate":
128
- try:
129
- gen_path = os.path.join(docs_path, "validation_qa.json")
130
- generate_validation_qa(
131
- docs_path=docs_path,
132
- output_path=gen_path,
133
- llm_model=req.llm_model if hasattr(req, "llm_model") else "gemini-2.5-flash-lite"
134
- )
135
- validation_set = gen_path
136
- logger.info("Generated new validation QA set at: %s", validation_set)
137
- except Exception as e:
138
- logger.exception("Failed to generate validation QA dataset: %s", e)
139
- raise HTTPException(status_code=500, detail=f"Failed to generate validation QA dataset: {e}")
140
 
141
- # Optimize
142
  start_time = time.time()
143
  best, results = rag.optimize(
144
  validation_set=validation_set,
@@ -147,10 +130,8 @@ def optimize_rag(req: OptimizeRequest):
147
  search_type=req.search_type
148
  )
149
  elapsed = time.time() - start_time
150
-
151
  run_id = f"opt_{int(time.time())}"
152
 
153
- # Corpus stats
154
  try:
155
  corpus_stats = {
156
  "num_docs": len(rag.documents),
@@ -160,7 +141,6 @@ def optimize_rag(req: OptimizeRequest):
160
  except Exception:
161
  corpus_stats = None
162
 
163
- # Leaderboard
164
  try:
165
  if Leaderboard:
166
  lb = Leaderboard()
@@ -193,12 +173,8 @@ def optimize_rag(req: OptimizeRequest):
193
  @app.post("/autotune_rag")
194
  def autotune_rag(req: AutotuneRequest):
195
  logger.info("Received autotune_rag request: %s", req.json())
196
-
197
  if AutoRAGTuner is None or RAGMint is None:
198
- raise HTTPException(
199
- status_code=500,
200
- detail=f"Ragmint autotuner/RAGMint imports failed: {_import_error}"
201
- )
202
 
203
  docs_path = req.docs_path or DEFAULT_DATA_DIR
204
  if not os.path.isdir(docs_path):
@@ -206,12 +182,8 @@ def autotune_rag(req: AutotuneRequest):
206
 
207
  try:
208
  start_time = time.time()
209
-
210
  tuner = AutoRAGTuner(docs_path=docs_path)
211
- rec = tuner.recommend(
212
- embedding_model=req.embedding_model,
213
- num_chunk_pairs=req.num_chunk_pairs
214
- )
215
 
216
  chunk_candidates = tuner.suggest_chunk_sizes(
217
  model_name=rec.get("embedding_model"),
@@ -232,39 +204,27 @@ def autotune_rag(req: AutotuneRequest):
232
  strategies=[rec["strategy"]],
233
  )
234
 
235
- # Validation selection
236
  validation_set = None
237
  validation_choice = (req.validation_choice or "").strip()
238
  default_val_path = os.path.join(docs_path, "validation_qa.jsonl")
239
-
240
  if not validation_choice:
241
  if os.path.exists(default_val_path):
242
  validation_set = default_val_path
243
- logger.info("Using default validation set: %s", validation_set)
244
  else:
245
- logger.warning("No validation_choice provided and no default found.")
246
  validation_set = None
247
-
248
  elif "/" in validation_choice and not os.path.exists(validation_choice):
249
  validation_set = validation_choice
250
-
251
  elif os.path.exists(validation_choice):
252
  validation_set = validation_choice
253
-
254
  elif validation_choice.lower() == "generate":
255
- try:
256
- gen_path = os.path.join(docs_path, "validation_qa.json")
257
- generate_validation_qa(
258
- docs_path=docs_path,
259
- output_path=gen_path,
260
- llm_model=req.llm_model if hasattr(req, "llm_model") else "gemini-2.5-flash-lite",
261
- )
262
- validation_set = gen_path
263
- except Exception as e:
264
- logger.exception("Failed to generate validation QA dataset: %s", e)
265
- raise HTTPException(status_code=500, detail=f"Failed to generate validation QA dataset: {e}")
266
 
267
- # Full optimize
268
  best, results = rag.optimize(
269
  validation_set=validation_set,
270
  metric=req.metric,
@@ -272,10 +232,8 @@ def autotune_rag(req: AutotuneRequest):
272
  trials=req.trials,
273
  )
274
  elapsed = time.time() - start_time
275
-
276
  run_id = f"autotune_{int(time.time())}"
277
 
278
- # Corpus stats
279
  try:
280
  corpus_stats = {
281
  "num_docs": len(rag.documents),
@@ -285,7 +243,6 @@ def autotune_rag(req: AutotuneRequest):
285
  except Exception:
286
  corpus_stats = None
287
 
288
- # Leaderboard
289
  try:
290
  if Leaderboard:
291
  lb = Leaderboard()
@@ -320,12 +277,11 @@ def autotune_rag(req: AutotuneRequest):
320
  @app.post("/generate_validation_qa")
321
  def generate_qa(req: QARequest):
322
  logger.info("Received generate_validation_qa request: %s", req.json())
323
-
324
  if generate_validation_qa is None:
325
  raise HTTPException(status_code=500, detail=f"Ragmint imports failed: {_import_error}")
326
 
327
  try:
328
- out_path = f"data/docs/validation_qa.json"
329
  os.makedirs(os.path.dirname(out_path), exist_ok=True)
330
 
331
  generate_validation_qa(
@@ -340,25 +296,14 @@ def generate_qa(req: QARequest):
340
  with open(out_path, "r", encoding="utf-8") as f:
341
  data = json.load(f)
342
 
343
- return {
344
- "status": "finished",
345
- "output_path": out_path,
346
- "preview_count": len(data),
347
- "sample": data[:5],
348
- }
349
 
350
  except Exception as exc:
351
  logger.exception("generate_validation_qa failed")
352
  raise HTTPException(status_code=500, detail=str(exc))
353
 
354
 
355
- # -----------------------
356
- # FastAPI launch
357
- # -----------------------
358
-
359
- def main():
360
- uvicorn.run(app, host="0.0.0.0", port=8000, log_level="info")
361
-
362
-
363
  if __name__ == "__main__":
364
- main()
 
 
1
+ # api.py
2
  from __future__ import annotations
3
  import os
4
  import json
5
  import logging
6
  import time
7
+ import shutil
8
 
9
  from models import OptimizeRequest, QARequest, AutotuneRequest
10
  from fastapi import FastAPI, HTTPException, UploadFile, File, Form
11
  from fastapi.middleware.cors import CORSMiddleware
 
 
12
 
13
  try:
14
  from ragmint.autotuner import AutoRAGTuner
 
33
  logging.basicConfig(level=logging.INFO)
34
  logger = logging.getLogger("ragmint_mcp_server")
35
 
36
+ # FastAPI app (exported for mounting)
37
  app = FastAPI(title="Ragmint MCP Server", version="0.1.0")
38
  app.add_middleware(
39
  CORSMiddleware,
 
43
  allow_headers=["*"],
44
  )
45
 
46
+ # Use repo-local data folder (not parent dirs)
47
+ DEFAULT_DATA_DIR = "data/docs"
48
  LEADERBOARD_STORAGE = "experiments/leaderboard.jsonl"
 
49
 
50
+ # ensure folders exist
51
+ os.makedirs(DEFAULT_DATA_DIR, exist_ok=True)
52
+ os.makedirs("experiments", exist_ok=True)
53
 
54
  @app.get("/health")
55
  def health():
 
59
  "import_error": str(_import_error) if _import_error else None,
60
  }
61
 
 
62
  @app.post("/upload_docs")
63
  async def upload_docs(
64
+ docs_path: str = Form(...),
65
  files: list[UploadFile] = File(...)
66
  ):
67
+ os.makedirs(docs_path, exist_ok=True)
68
  saved_files = []
 
69
  for file in files:
70
  file_path = os.path.join(docs_path, file.filename)
71
  with open(file_path, "wb") as f:
72
  shutil.copyfileobj(file.file, f)
73
  saved_files.append(file.filename)
 
74
  return {"status": "ok", "uploaded_files": saved_files, "docs_path": docs_path}
75
 
76
  @app.post("/optimize_rag")
77
  def optimize_rag(req: OptimizeRequest):
78
  logger.info("Received optimize_rag request: %s", req.json())
 
79
  if RAGMint is None:
80
+ raise HTTPException(status_code=500, detail=f"Ragmint imports failed: {_import_error}")
 
 
 
81
 
82
  docs_path = req.docs_path or DEFAULT_DATA_DIR
83
  if not os.path.isdir(docs_path):
84
  raise HTTPException(status_code=400, detail=f"docs_path does not exist: {docs_path}")
85
 
86
  try:
 
87
  rag = RAGMint(
88
  docs_path=docs_path,
89
  retrievers=req.retriever,
 
94
  strategies=req.strategy,
95
  )
96
 
97
+ # validation set handling
98
  validation_set = None
99
  validation_choice = (req.validation_choice or "").strip()
100
  default_val_path = os.path.join(docs_path, "validation_qa.json")
101
 
 
102
  if not validation_choice:
103
  if os.path.exists(default_val_path):
104
  validation_set = default_val_path
 
106
  else:
107
  logger.warning("No validation_choice provided and no default found.")
108
  validation_set = None
 
 
109
  elif "/" in validation_choice and not os.path.exists(validation_choice):
110
  validation_set = validation_choice
111
+ logger.info("Using HF dataset as validation: %s", validation_set)
 
 
112
  elif os.path.exists(validation_choice):
113
  validation_set = validation_choice
114
  logger.info("Using local validation dataset: %s", validation_set)
 
 
115
  elif validation_choice.lower() == "generate":
116
+ gen_path = os.path.join(docs_path, "validation_qa.json")
117
+ generate_validation_qa(
118
+ docs_path=docs_path,
119
+ output_path=gen_path,
120
+ llm_model=req.llm_model if hasattr(req, "llm_model") else "gemini-2.5-flash-lite"
121
+ )
122
+ validation_set = gen_path
123
+ logger.info("Generated validation QA at: %s", validation_set)
 
 
 
 
124
 
 
125
  start_time = time.time()
126
  best, results = rag.optimize(
127
  validation_set=validation_set,
 
130
  search_type=req.search_type
131
  )
132
  elapsed = time.time() - start_time
 
133
  run_id = f"opt_{int(time.time())}"
134
 
 
135
  try:
136
  corpus_stats = {
137
  "num_docs": len(rag.documents),
 
141
  except Exception:
142
  corpus_stats = None
143
 
 
144
  try:
145
  if Leaderboard:
146
  lb = Leaderboard()
 
173
  @app.post("/autotune_rag")
174
  def autotune_rag(req: AutotuneRequest):
175
  logger.info("Received autotune_rag request: %s", req.json())
 
176
  if AutoRAGTuner is None or RAGMint is None:
177
+ raise HTTPException(status_code=500, detail=f"Ragmint autotuner/RAGMint imports failed: {_import_error}")
 
 
 
178
 
179
  docs_path = req.docs_path or DEFAULT_DATA_DIR
180
  if not os.path.isdir(docs_path):
 
182
 
183
  try:
184
  start_time = time.time()
 
185
  tuner = AutoRAGTuner(docs_path=docs_path)
186
+ rec = tuner.recommend(embedding_model=req.embedding_model, num_chunk_pairs=req.num_chunk_pairs)
 
 
 
187
 
188
  chunk_candidates = tuner.suggest_chunk_sizes(
189
  model_name=rec.get("embedding_model"),
 
204
  strategies=[rec["strategy"]],
205
  )
206
 
 
207
  validation_set = None
208
  validation_choice = (req.validation_choice or "").strip()
209
  default_val_path = os.path.join(docs_path, "validation_qa.jsonl")
 
210
  if not validation_choice:
211
  if os.path.exists(default_val_path):
212
  validation_set = default_val_path
 
213
  else:
 
214
  validation_set = None
 
215
  elif "/" in validation_choice and not os.path.exists(validation_choice):
216
  validation_set = validation_choice
 
217
  elif os.path.exists(validation_choice):
218
  validation_set = validation_choice
 
219
  elif validation_choice.lower() == "generate":
220
+ gen_path = os.path.join(docs_path, "validation_qa.json")
221
+ generate_validation_qa(
222
+ docs_path=docs_path,
223
+ output_path=gen_path,
224
+ llm_model=req.llm_model if hasattr(req, "llm_model") else "gemini-2.5-flash-lite",
225
+ )
226
+ validation_set = gen_path
 
 
 
 
227
 
 
228
  best, results = rag.optimize(
229
  validation_set=validation_set,
230
  metric=req.metric,
 
232
  trials=req.trials,
233
  )
234
  elapsed = time.time() - start_time
 
235
  run_id = f"autotune_{int(time.time())}"
236
 
 
237
  try:
238
  corpus_stats = {
239
  "num_docs": len(rag.documents),
 
243
  except Exception:
244
  corpus_stats = None
245
 
 
246
  try:
247
  if Leaderboard:
248
  lb = Leaderboard()
 
277
  @app.post("/generate_validation_qa")
278
  def generate_qa(req: QARequest):
279
  logger.info("Received generate_validation_qa request: %s", req.json())
 
280
  if generate_validation_qa is None:
281
  raise HTTPException(status_code=500, detail=f"Ragmint imports failed: {_import_error}")
282
 
283
  try:
284
+ out_path = os.path.join("data", "docs", "validation_qa.json")
285
  os.makedirs(os.path.dirname(out_path), exist_ok=True)
286
 
287
  generate_validation_qa(
 
296
  with open(out_path, "r", encoding="utf-8") as f:
297
  data = json.load(f)
298
 
299
+ return {"status": "finished", "output_path": out_path, "preview_count": len(data), "sample": data[:5]}
 
 
 
 
 
300
 
301
  except Exception as exc:
302
  logger.exception("generate_validation_qa failed")
303
  raise HTTPException(status_code=500, detail=str(exc))
304
 
305
 
306
+ # only run uvicorn if script is executed directly
 
 
 
 
 
 
 
307
  if __name__ == "__main__":
308
+ import uvicorn as _uvicorn
309
+ _uvicorn.run(app, host="0.0.0.0", port=7860, log_level="info")
app.py CHANGED
@@ -1,122 +1,88 @@
 
1
  import gradio as gr
2
  import requests
3
  import json
4
- from models import OptimizeRequest, AutotuneRequest, QARequest
5
  import os
6
- import threading
7
  import uvicorn
8
- from api import app as fastapi_app
9
-
10
- API_URL = "http://127.0.0.1:7861"
11
-
12
- def start_fastapi():
13
- uvicorn.run(fastapi_app, host="0.0.0.0", port=7861, log_level="info")
14
 
15
- # Start FastAPI in a background thread
16
- threading.Thread(target=start_fastapi, daemon=True).start()
17
 
18
- # -------------------------------
19
- # Helper to call API
20
- # -------------------------------
21
  def call_api(endpoint: str, payload: dict) -> str:
22
  try:
23
- r = requests.post(f"{API_URL}/{endpoint}", json=payload)
24
  return json.dumps(r.json(), indent=2)
25
  except Exception as e:
26
  return str(e)
27
 
28
-
29
- # -------------------------------
30
- # MCP Tool Wrappers
31
- # -------------------------------
32
  def upload_docs_tool(files, docs_path="data/docs"):
33
-
34
  os.makedirs(docs_path, exist_ok=True)
35
- uploaded_files = []
36
-
37
- for file_path in files:
38
- filename = os.path.basename(file_path)
39
- dest_path = os.path.join(docs_path, filename)
40
- import shutil
41
- shutil.copy(file_path, dest_path)
42
- uploaded_files.append(filename)
43
-
44
- return {"status": "ok", "uploaded_files": uploaded_files, "docs_path": docs_path}
45
-
46
 
47
  def optimize_rag_tool(payload: str) -> str:
48
- return call_api("optimize_rag", json.loads(payload))
49
-
50
 
51
  def autotune_tool(payload: str) -> str:
52
- return call_api("autotune_rag", json.loads(payload))
53
-
54
 
55
  def generate_qa_tool(payload: str) -> str:
56
- return call_api("generate_validation_qa", json.loads(payload))
57
-
58
 
59
- # -------------------------------
60
- # Generate default JSON for models
61
- # -------------------------------
62
  def model_to_json(model_cls) -> str:
63
- defaults = {k: v.default for k, v in model_cls.__fields__.items()}
64
- return json.dumps(defaults, indent=2)
65
 
66
-
67
- # Default payloads
68
  DEFAULT_UPLOAD_PATH = "data/docs"
69
- DEFAULT_UPLOAD_FILES = [] # No files by default
70
  DEFAULT_OPTIMIZE_JSON = model_to_json(OptimizeRequest)
71
  DEFAULT_AUTOTUNE_JSON = model_to_json(AutotuneRequest)
72
  DEFAULT_QA_JSON = model_to_json(QARequest)
73
 
74
- # -------------------------------
75
- # Build Gradio interface
76
- # -------------------------------
77
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
78
- gr.Markdown("# Ragmint MCP Client")
79
-
80
- # Upload files section
81
  with gr.Column():
82
- gr.Markdown("## Upload Documents\nUpload files to a folder on the server.")
83
- upload_files = gr.File(
84
- file_types=[".txt", ".md", ".pdf"], # allowed extensions
85
- file_count="multiple", # allow multiple files
86
- type="filepath", # returns local file path
87
- label="Drag & Drop Files"
88
- )
89
  upload_path = gr.Textbox(value=DEFAULT_UPLOAD_PATH, label="Docs Path")
90
- upload_btn = gr.Button("Upload",variant='primary')
91
- upload_output = gr.Textbox(label="Response")
92
- upload_btn.click(upload_docs_tool, inputs=[upload_files, upload_path], outputs=upload_output)
93
  gr.Markdown("---")
94
 
95
- # Optimize RAG
96
  with gr.Column():
97
- gr.Markdown("## Optimize RAG\nRun full RAG optimization with custom parameters.")
98
  optimize_input = gr.Textbox(lines=12, value=DEFAULT_OPTIMIZE_JSON, label="OptimizeRequest JSON")
99
- optimize_btn = gr.Button("Submit",variant='primary')
100
- optimize_output = gr.Textbox(lines=15, label="Response")
101
- optimize_btn.click(optimize_rag_tool, inputs=optimize_input, outputs=optimize_output)
102
  gr.Markdown("---")
103
 
104
- # Autotune RAG
105
  with gr.Column():
106
- gr.Markdown("## Autotune RAG\nRun AutoRAG tuner and full optimization.")
107
  autotune_input = gr.Textbox(lines=12, value=DEFAULT_AUTOTUNE_JSON, label="AutotuneRequest JSON")
108
- autotune_btn = gr.Button("Submit",variant='primary')
109
- autotune_output = gr.Textbox(lines=15, label="Response")
110
- autotune_btn.click(autotune_tool, inputs=autotune_input, outputs=autotune_output)
111
  gr.Markdown("---")
112
 
113
- # Generate QA
114
  with gr.Column():
115
- gr.Markdown("## Generate QA\nGenerate validation QA dataset from documents.")
116
  qa_input = gr.Textbox(lines=12, value=DEFAULT_QA_JSON, label="QARequest JSON")
117
- qa_btn = gr.Button("Submit",variant='primary')
118
- qa_output = gr.Textbox(lines=15, label="Response")
119
- qa_btn.click(generate_qa_tool, inputs=qa_input, outputs=qa_output)
120
  gr.Markdown("---")
121
 
122
- demo.launch(mcp_server=True)
 
 
 
 
 
 
1
+ # app.py
2
  import gradio as gr
3
  import requests
4
  import json
 
5
  import os
6
+ import shutil
7
  import uvicorn
8
+ from models import OptimizeRequest, AutotuneRequest, QARequest
9
+ from api import app as backend_app # import the FastAPI app we just saved
 
 
 
 
10
 
11
+ # Base URL for internal calls (same process)
12
+ BASE_INTERNAL = "http://127.0.0.1:7860"
13
 
 
 
 
14
  def call_api(endpoint: str, payload: dict) -> str:
15
  try:
16
+ r = requests.post(f"{BASE_INTERNAL}{endpoint}", json=payload, timeout=120)
17
  return json.dumps(r.json(), indent=2)
18
  except Exception as e:
19
  return str(e)
20
 
 
 
 
 
21
  def upload_docs_tool(files, docs_path="data/docs"):
 
22
  os.makedirs(docs_path, exist_ok=True)
23
+ saved = []
24
+ for f in files:
25
+ fname = os.path.basename(f)
26
+ dest = os.path.join(docs_path, fname)
27
+ shutil.copy(f, dest)
28
+ saved.append(fname)
29
+ return {"status": "ok", "uploaded_files": saved, "docs_path": docs_path}
 
 
 
 
30
 
31
  def optimize_rag_tool(payload: str) -> str:
32
+ return call_api("/optimize_rag", json.loads(payload))
 
33
 
34
  def autotune_tool(payload: str) -> str:
35
+ return call_api("/autotune_rag", json.loads(payload))
 
36
 
37
  def generate_qa_tool(payload: str) -> str:
38
+ return call_api("/generate_validation_qa", json.loads(payload))
 
39
 
 
 
 
40
  def model_to_json(model_cls) -> str:
41
+ return json.dumps({k: v.default for k, v in model_cls.__fields__.items()}, indent=2)
 
42
 
 
 
43
  DEFAULT_UPLOAD_PATH = "data/docs"
 
44
  DEFAULT_OPTIMIZE_JSON = model_to_json(OptimizeRequest)
45
  DEFAULT_AUTOTUNE_JSON = model_to_json(AutotuneRequest)
46
  DEFAULT_QA_JSON = model_to_json(QARequest)
47
 
 
 
 
48
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
49
+ gr.Markdown("# Ragmint MCP Client (UI)")
 
 
50
  with gr.Column():
51
+ gr.Markdown("## Upload Documents")
52
+ upload_files = gr.File(file_count="multiple", type="filepath")
 
 
 
 
 
53
  upload_path = gr.Textbox(value=DEFAULT_UPLOAD_PATH, label="Docs Path")
54
+ upload_btn = gr.Button("Upload", variant="primary")
55
+ upload_out = gr.Textbox()
56
+ upload_btn.click(upload_docs_tool, inputs=[upload_files, upload_path], outputs=upload_out)
57
  gr.Markdown("---")
58
 
 
59
  with gr.Column():
60
+ gr.Markdown("## Optimize RAG")
61
  optimize_input = gr.Textbox(lines=12, value=DEFAULT_OPTIMIZE_JSON, label="OptimizeRequest JSON")
62
+ optimize_btn = gr.Button("Submit", variant="primary")
63
+ optimize_out = gr.Textbox(lines=15)
64
+ optimize_btn.click(optimize_rag_tool, inputs=optimize_input, outputs=optimize_out)
65
  gr.Markdown("---")
66
 
 
67
  with gr.Column():
68
+ gr.Markdown("## Autotune RAG")
69
  autotune_input = gr.Textbox(lines=12, value=DEFAULT_AUTOTUNE_JSON, label="AutotuneRequest JSON")
70
+ autotune_btn = gr.Button("Submit", variant="primary")
71
+ autotune_out = gr.Textbox(lines=15)
72
+ autotune_btn.click(autotune_tool, inputs=autotune_input, outputs=autotune_out)
73
  gr.Markdown("---")
74
 
 
75
  with gr.Column():
76
+ gr.Markdown("## Generate QA")
77
  qa_input = gr.Textbox(lines=12, value=DEFAULT_QA_JSON, label="QARequest JSON")
78
+ qa_btn = gr.Button("Submit", variant="primary")
79
+ qa_out = gr.Textbox(lines=15)
80
+ qa_btn.click(generate_qa_tool, inputs=qa_input, outputs=qa_out)
81
  gr.Markdown("---")
82
 
83
+ # mount the Gradio app on FastAPI at root ("/")
84
+ gr.mount_gradio_app(backend_app, demo, path="/")
85
+
86
+ # When run directly, serve with uvicorn (HF will run this)
87
+ if __name__ == "__main__":
88
+ uvicorn.run(backend_app, host="0.0.0.0", port=7860, log_level="info")
server.py DELETED
@@ -1,7 +0,0 @@
1
- import threading
2
- from api import main
3
-
4
- def start():
5
- threading.Thread(target=main, daemon=True).start()
6
-
7
- start()