Pontonkid commited on
Commit
1ae0de7
·
verified ·
1 Parent(s): 892c927

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -80
app.py CHANGED
@@ -1,28 +1,24 @@
1
  # app.py
2
  import os
3
  import threading
4
- import tempfile
5
- import json
6
  import datetime
 
7
  from pathlib import Path
8
  import requests
9
-
 
10
  import gradio as gr
11
  from fastapi import FastAPI, UploadFile, File
12
  import uvicorn
13
- from reportlab.lib.pagesizes import letter
14
- from reportlab.pdfgen import canvas
15
 
16
  # -----------------------
17
  # CONFIG
18
  # -----------------------
19
- REPORT_DIR = Path("./reports")
20
- REPORT_DIR.mkdir(exist_ok=True)
21
-
22
  FILE_STORAGE = Path("file_storage")
23
  FILE_STORAGE.mkdir(exist_ok=True)
 
 
24
 
25
- # MCP ports
26
  FILE_SERVER_PORT = 8001
27
  EXECUTOR_PORT = 8002
28
  MEMORY_PORT = 8003
@@ -30,10 +26,11 @@ MEMORY_PORT = 8003
30
  # -----------------------
31
  # MCP SERVERS
32
  # -----------------------
33
-
34
- # --- File Server ---
35
  file_app = FastAPI()
 
 
36
 
 
37
  @file_app.post("/upload")
38
  async def upload_file(file: UploadFile = File(...)):
39
  dest = FILE_STORAGE / file.filename
@@ -42,7 +39,7 @@ async def upload_file(file: UploadFile = File(...)):
42
  content = content.decode("utf-8", errors="ignore")
43
  with open(dest, "w", encoding="utf-8") as f:
44
  f.write(content)
45
- return {"status":"ok","filename":file.filename,"path":str(dest)}
46
 
47
  @file_app.get("/list")
48
  def list_files():
@@ -52,11 +49,10 @@ def list_files():
52
  def read_file(name: str):
53
  fpath = FILE_STORAGE / name
54
  if not fpath.exists():
55
- return {"error":"not found"}
56
  return {"filename": name, "content": fpath.read_text(encoding="utf-8")}
57
 
58
  # --- Executor Server ---
59
- executor_app = FastAPI()
60
  EXECUTOR_DB = Path("executor_db")
61
  EXECUTOR_DB.mkdir(exist_ok=True)
62
 
@@ -74,10 +70,9 @@ def apply_patch(req: dict):
74
  existing = json.loads(fname.read_text())
75
  existing.append(rec)
76
  fname.write_text(json.dumps(existing, indent=2))
77
- return {"status":"applied","record": rec}
78
 
79
  # --- Memory Server ---
80
- memory_app = FastAPI()
81
  MEMORY_DB = Path("memory_db")
82
  MEMORY_DB.mkdir(exist_ok=True)
83
  MEMORY_FILE = MEMORY_DB / "memory.json"
@@ -86,12 +81,12 @@ if not MEMORY_FILE.exists():
86
 
87
  @memory_app.post("/set")
88
  def set_memory(item: dict):
 
89
  key = item.get("key")
90
  value = item.get("value")
91
- m = json.loads(MEMORY_FILE.read_text())
92
  m[key] = value
93
  MEMORY_FILE.write_text(json.dumps(m, indent=2))
94
- return {"status":"ok","key":key}
95
 
96
  @memory_app.get("/get/{key}")
97
  def get_memory(key: str):
@@ -101,35 +96,44 @@ def get_memory(key: str):
101
  # -----------------------
102
  # HELPER FUNCTIONS
103
  # -----------------------
104
- def upload_file_to_mcp(filepath, filename):
105
- url = f"http://localhost:{FILE_SERVER_PORT}/upload"
106
- with open(filepath, "rb") as f:
107
- files = {"file": (filename, f)}
108
- r = requests.post(url, files=files, timeout=30)
109
- r.raise_for_status()
110
- return r.json()
111
-
112
  def list_mcp_files():
113
  try:
114
- return requests.get(f"http://localhost:{FILE_SERVER_PORT}/list").json()
 
115
  except:
116
  return {"files": [f.name for f in FILE_STORAGE.iterdir() if f.is_file()]}
117
 
118
  def read_mcp_file(name):
119
- return requests.get(f"http://localhost:{FILE_SERVER_PORT}/read/{name}").json()
 
 
 
 
120
 
121
  def apply_patch_mcp(filename, action, params=None):
122
  payload = {"filename": filename, "action": action, "params": params or {}}
123
- return requests.post(f"http://localhost:{EXECUTOR_PORT}/apply", json=payload).json()
 
 
 
 
124
 
125
  def memory_set(key, value):
126
- return requests.post(f"http://localhost:{MEMORY_PORT}/set", json={"key":key,"value":value}).json()
 
 
 
 
127
 
128
  def memory_get(key):
129
- return requests.get(f"http://localhost:{MEMORY_PORT}/get/{key}").json()
 
 
 
 
130
 
131
  # -----------------------
132
- # LOG ANALYSIS & PLAN
133
  # -----------------------
134
  def parse_log_text(txt):
135
  lines = txt.splitlines()
@@ -143,7 +147,7 @@ def analyze_and_plan(filename):
143
  return {"summary": "File not found", "issues": [], "suggestions": [], "plan_text": ""}
144
  text = r.get("content","")
145
  parsed = parse_log_text(text)
146
- summary = f"Detected {len(parsed['errors'])} errors and {len(parsed['warnings'])} warnings"
147
  issues = parsed["errors"][:10] + parsed["warnings"][:10]
148
  suggestions = [
149
  "Investigate top errors",
@@ -185,17 +189,6 @@ def generate_incident_report(filename, summary, issues, suggestions):
185
  c.save()
186
  return str(out)
187
 
188
- def apply_fix_action(filename, action_key):
189
- mapping = {
190
- "increase_timeout": ("update_timeout", {"timeout": 60}),
191
- "increase_retries": ("increase_retries", {"retries": 3}),
192
- "mark_fixed": ("mark_fixed", {})
193
- }
194
- action, params = mapping.get(action_key, ("custom_action", {"note": action_key}))
195
- res = apply_patch_mcp(filename, action, params)
196
- memory_set(f"last_patch_{filename}", json.dumps(res))
197
- return res
198
-
199
  # -----------------------
200
  # GRADIO UI
201
  # -----------------------
@@ -217,52 +210,42 @@ with gr.Blocks() as demo:
217
  plan_box = gr.Textbox(label="Agent Plan / Reasoning", lines=6)
218
  report_download = gr.File(label="Last Report (download)")
219
 
220
- # Refresh or initialize file dropdown
221
- def refresh_files():
222
- try:
223
- resp = list_mcp_files()
224
- files = resp.get("files", [])
225
- if not files:
226
- files = [f.name for f in FILE_STORAGE.iterdir() if f.is_file()]
227
- return files
228
- except Exception as e:
229
- print("Error fetching files:", e)
230
- return []
231
 
232
- files_list.choices = refresh_files()
 
233
 
234
- btn_refresh.click(fn=refresh_files, outputs=files_list)
235
 
236
  def on_upload(file_obj):
237
  if file_obj is None:
238
  return refresh_files()
239
- try:
240
- content = file_obj.read()
241
- if isinstance(content, bytes):
242
- content = content.decode("utf-8", errors="ignore")
243
- tmp = FILE_STORAGE / file_obj.name
244
- with open(tmp, "w", encoding="utf-8") as f:
245
- f.write(content)
246
- return refresh_files()
247
- except Exception as e:
248
- print("Upload error:", e)
249
- return refresh_files()
250
 
251
  btn_upload.click(fn=on_upload, inputs=[upload], outputs=[files_list])
252
 
253
  def analyze_selected(fname):
254
  if not fname:
255
- return "Select file first", "", "", "", None
256
  out = analyze_and_plan(fname)
257
  report_path = generate_incident_report(fname, out["summary"], out["issues"], out["suggestions"])
258
- return out["summary"], "\n".join(out["issues"]), "\n".join(out["suggestions"]), out["plan_text"], gr.File.update(value=report_path)
 
259
 
260
- btn_analyze.click(fn=analyze_selected, inputs=[files_list], outputs=[summary_box, issues_box, suggestions_box, plan_box, report_download])
 
261
 
262
  def apply_action(fname, action_key):
263
  if not fname:
264
- return "Select file first"
265
- res = apply_fix_action(fname, action_key)
266
  return json.dumps(res, indent=2)
267
 
268
  btn_apply.click(fn=apply_action, inputs=[files_list, apply_dropdown], outputs=[plan_box])
@@ -270,16 +253,13 @@ with gr.Blocks() as demo:
270
  # -----------------------
271
  # START MCP SERVERS
272
  # -----------------------
273
- def start_file_server():
274
- uvicorn.run(file_app, host="0.0.0.0", port=FILE_SERVER_PORT, log_level="error")
275
- def start_executor_server():
276
- uvicorn.run(executor_app, host="0.0.0.0", port=EXECUTOR_PORT, log_level="error")
277
- def start_memory_server():
278
- uvicorn.run(memory_app, host="0.0.0.0", port=MEMORY_PORT, log_level="error")
279
 
280
  threading.Thread(target=start_file_server, daemon=True).start()
281
  threading.Thread(target=start_executor_server, daemon=True).start()
282
  threading.Thread(target=start_memory_server, daemon=True).start()
283
 
284
  if __name__ == "__main__":
285
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
1
  # app.py
2
  import os
3
  import threading
 
 
4
  import datetime
5
+ import json
6
  from pathlib import Path
7
  import requests
8
+ from reportlab.lib.pagesizes import letter
9
+ from reportlab.pdfgen import canvas
10
  import gradio as gr
11
  from fastapi import FastAPI, UploadFile, File
12
  import uvicorn
 
 
13
 
14
  # -----------------------
15
  # CONFIG
16
  # -----------------------
 
 
 
17
  FILE_STORAGE = Path("file_storage")
18
  FILE_STORAGE.mkdir(exist_ok=True)
19
+ REPORT_DIR = Path("reports")
20
+ REPORT_DIR.mkdir(exist_ok=True)
21
 
 
22
  FILE_SERVER_PORT = 8001
23
  EXECUTOR_PORT = 8002
24
  MEMORY_PORT = 8003
 
26
  # -----------------------
27
  # MCP SERVERS
28
  # -----------------------
 
 
29
  file_app = FastAPI()
30
+ executor_app = FastAPI()
31
+ memory_app = FastAPI()
32
 
33
+ # --- File Server ---
34
  @file_app.post("/upload")
35
  async def upload_file(file: UploadFile = File(...)):
36
  dest = FILE_STORAGE / file.filename
 
39
  content = content.decode("utf-8", errors="ignore")
40
  with open(dest, "w", encoding="utf-8") as f:
41
  f.write(content)
42
+ return {"status": "ok", "filename": file.filename}
43
 
44
  @file_app.get("/list")
45
  def list_files():
 
49
  def read_file(name: str):
50
  fpath = FILE_STORAGE / name
51
  if not fpath.exists():
52
+ return {"error": "not found"}
53
  return {"filename": name, "content": fpath.read_text(encoding="utf-8")}
54
 
55
  # --- Executor Server ---
 
56
  EXECUTOR_DB = Path("executor_db")
57
  EXECUTOR_DB.mkdir(exist_ok=True)
58
 
 
70
  existing = json.loads(fname.read_text())
71
  existing.append(rec)
72
  fname.write_text(json.dumps(existing, indent=2))
73
+ return {"status": "applied", "record": rec}
74
 
75
  # --- Memory Server ---
 
76
  MEMORY_DB = Path("memory_db")
77
  MEMORY_DB.mkdir(exist_ok=True)
78
  MEMORY_FILE = MEMORY_DB / "memory.json"
 
81
 
82
  @memory_app.post("/set")
83
  def set_memory(item: dict):
84
+ m = json.loads(MEMORY_FILE.read_text())
85
  key = item.get("key")
86
  value = item.get("value")
 
87
  m[key] = value
88
  MEMORY_FILE.write_text(json.dumps(m, indent=2))
89
+ return {"status": "ok", "key": key}
90
 
91
  @memory_app.get("/get/{key}")
92
  def get_memory(key: str):
 
96
  # -----------------------
97
  # HELPER FUNCTIONS
98
  # -----------------------
 
 
 
 
 
 
 
 
99
  def list_mcp_files():
100
  try:
101
+ r = requests.get(f"http://localhost:{FILE_SERVER_PORT}/list", timeout=5)
102
+ return r.json()
103
  except:
104
  return {"files": [f.name for f in FILE_STORAGE.iterdir() if f.is_file()]}
105
 
106
  def read_mcp_file(name):
107
+ try:
108
+ r = requests.get(f"http://localhost:{FILE_SERVER_PORT}/read/{name}", timeout=5)
109
+ return r.json()
110
+ except:
111
+ return {"error": "file read failed"}
112
 
113
  def apply_patch_mcp(filename, action, params=None):
114
  payload = {"filename": filename, "action": action, "params": params or {}}
115
+ try:
116
+ r = requests.post(f"http://localhost:{EXECUTOR_PORT}/apply", json=payload, timeout=5)
117
+ return r.json()
118
+ except:
119
+ return {"error": "executor not reachable"}
120
 
121
  def memory_set(key, value):
122
+ try:
123
+ r = requests.post(f"http://localhost:{MEMORY_PORT}/set", json={"key": key, "value": value}, timeout=5)
124
+ return r.json()
125
+ except:
126
+ return {"error": "memory not reachable"}
127
 
128
  def memory_get(key):
129
+ try:
130
+ r = requests.get(f"http://localhost:{MEMORY_PORT}/get/{key}", timeout=5)
131
+ return r.json()
132
+ except:
133
+ return {"error": "memory not reachable"}
134
 
135
  # -----------------------
136
+ # LOG ANALYSIS
137
  # -----------------------
138
  def parse_log_text(txt):
139
  lines = txt.splitlines()
 
147
  return {"summary": "File not found", "issues": [], "suggestions": [], "plan_text": ""}
148
  text = r.get("content","")
149
  parsed = parse_log_text(text)
150
+ summary = f"Detected {len(parsed['errors'])} errors and {len(parsed['warnings'])} warnings in {parsed['total_lines']} lines."
151
  issues = parsed["errors"][:10] + parsed["warnings"][:10]
152
  suggestions = [
153
  "Investigate top errors",
 
189
  c.save()
190
  return str(out)
191
 
 
 
 
 
 
 
 
 
 
 
 
192
  # -----------------------
193
  # GRADIO UI
194
  # -----------------------
 
210
  plan_box = gr.Textbox(label="Agent Plan / Reasoning", lines=6)
211
  report_download = gr.File(label="Last Report (download)")
212
 
213
+ # Initialize dropdown
214
+ files_list.choices = [f for f in FILE_STORAGE.iterdir() if f.is_file()]
 
 
 
 
 
 
 
 
 
215
 
216
+ def refresh_files():
217
+ return list_mcp_files().get("files", [])
218
 
219
+ btn_refresh.click(fn=refresh_files, outputs=[files_list])
220
 
221
  def on_upload(file_obj):
222
  if file_obj is None:
223
  return refresh_files()
224
+ content = file_obj.read()
225
+ if isinstance(content, bytes):
226
+ content = content.decode("utf-8", errors="ignore")
227
+ tmp = FILE_STORAGE / file_obj.name
228
+ with open(tmp, "w", encoding="utf-8") as f:
229
+ f.write(content)
230
+ return refresh_files()
 
 
 
 
231
 
232
  btn_upload.click(fn=on_upload, inputs=[upload], outputs=[files_list])
233
 
234
  def analyze_selected(fname):
235
  if not fname:
236
+ return "", "", "", "", None
237
  out = analyze_and_plan(fname)
238
  report_path = generate_incident_report(fname, out["summary"], out["issues"], out["suggestions"])
239
+ return (out["summary"], "\n".join(out["issues"]), "\n".join(out["suggestions"]),
240
+ out["plan_text"], gr.File.update(value=report_path))
241
 
242
+ btn_analyze.click(fn=analyze_selected, inputs=[files_list],
243
+ outputs=[summary_box, issues_box, suggestions_box, plan_box, report_download])
244
 
245
  def apply_action(fname, action_key):
246
  if not fname:
247
+ return ""
248
+ res = apply_patch_mcp(fname, action_key)
249
  return json.dumps(res, indent=2)
250
 
251
  btn_apply.click(fn=apply_action, inputs=[files_list, apply_dropdown], outputs=[plan_box])
 
253
  # -----------------------
254
  # START MCP SERVERS
255
  # -----------------------
256
+ def start_file_server(): uvicorn.run(file_app, host="0.0.0.0", port=FILE_SERVER_PORT, log_level="error")
257
+ def start_executor_server(): uvicorn.run(executor_app, host="0.0.0.0", port=EXECUTOR_PORT, log_level="error")
258
+ def start_memory_server(): uvicorn.run(memory_app, host="0.0.0.0", port=MEMORY_PORT, log_level="error")
 
 
 
259
 
260
  threading.Thread(target=start_file_server, daemon=True).start()
261
  threading.Thread(target=start_executor_server, daemon=True).start()
262
  threading.Thread(target=start_memory_server, daemon=True).start()
263
 
264
  if __name__ == "__main__":
265
+ demo.launch(server_name="0.0.0.0", server_port=7860)