keshan commited on
Commit
3921e25
·
verified ·
1 Parent(s): 4d3c8f5

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -0
app.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import httpx
3
+ import json
4
+ import os
5
+ from dotenv import load_dotenv
6
+
7
+ # Load environment variables from .env file
8
+ load_dotenv()
9
+
10
+ MODAL_MCP_ENDPOINT = os.getenv("MODAL_MCP_ENDPOINT", "YOUR_MODAL_MCP_ENDPOINT_HERE")
11
+ BANDIT_TOOL_NAME = "bandit"
12
+
13
+ async def call_bandit_tool_on_modal(tool_parameters_json: str):
14
+ if MODAL_MCP_ENDPOINT == "YOUR_MODAL_MCP_ENDPOINT_HERE" or not MODAL_MCP_ENDPOINT:
15
+ return {"error": "MODAL_MCP_ENDPOINT is not set. Please create a .env file in the 'mcp_deploy' directory with MODAL_MCP_ENDPOINT='your_url' or set it as an environment variable."}
16
+
17
+ try:
18
+ tool_parameters = json.loads(tool_parameters_json)
19
+ except json.JSONDecodeError as e:
20
+ return {"error": "Invalid JSON format for tool parameters.", "details": str(e)}
21
+
22
+ # Ensure 'code' parameter is present, as Bandit expects it.
23
+ if "code" not in tool_parameters:
24
+ return {"error": "Missing 'code' parameter in JSON. Bandit requires a 'code' field with the Python code string to analyze."}
25
+
26
+ payload = {
27
+ "tool_name": BANDIT_TOOL_NAME,
28
+ "tool_params": tool_parameters,
29
+ "agent_id": "gradio-bandit-ui",
30
+ "session_id": "default_session"
31
+ }
32
+
33
+ async with httpx.AsyncClient(timeout=60.0) as client:
34
+ try:
35
+ print(f"Calling MCP tool: {BANDIT_TOOL_NAME} at {MODAL_MCP_ENDPOINT} with params: {tool_parameters}")
36
+ response = await client.post(MODAL_MCP_ENDPOINT, json=payload)
37
+ response.raise_for_status()
38
+ print(response.json())
39
+
40
+ # Handle Modal's [response_dict, status_code] tuple format
41
+ raw_response_data = response.json()
42
+ if isinstance(raw_response_data, list) and len(raw_response_data) > 0 and isinstance(raw_response_data[0], dict):
43
+ actual_response = raw_response_data[0]
44
+ elif isinstance(raw_response_data, dict):
45
+ actual_response = raw_response_data
46
+ else:
47
+ return {"error": "Unexpected response format from MCP server", "details": raw_response_data}
48
+ return actual_response
49
+
50
+ except httpx.HTTPStatusError as e:
51
+ error_message = f"HTTP error: {e.response.status_code}"
52
+ try:
53
+ error_details = e.response.json()
54
+ error_message += f" - {json.dumps(error_details)}"
55
+ except json.JSONDecodeError:
56
+ error_message += f" - {e.response.text}"
57
+ return {"error": error_message}
58
+ except httpx.RequestError as e:
59
+ return {"error": f"Request error for {e.request.url!r}: {str(e)}"}
60
+ except Exception as e:
61
+ return {"error": f"An unexpected error occurred: {str(e)}"}
62
+
63
+
64
+ # Define Gradio inputs and outputs
65
+ tool_params_input = gr.Textbox(
66
+ label="Bandit Parameters (JSON string with 'code' field)",
67
+ placeholder='e.g., {\"code\": \"import os\nprint(os.listdir(\".\"))\"}',
68
+ lines=10,
69
+ info="Enter parameters as a valid JSON string. Must include a 'code' field containing the Python code to analyze."
70
+ )
71
+ output_display = gr.JSON(label="Bandit Analysis Output")
72
+
73
+ # Example for Bandit tool
74
+ bandit_example_code = """import subprocess\n\n# Example of a potential security risk with subprocess\nsubprocess.call("ls -l", shell=True)"""
75
+ bandit_example_params = json.dumps({"code": bandit_example_code}, indent=2)
76
+
77
+ # Create the Gradio interface
78
+ iface = gr.Interface(
79
+ fn=call_bandit_tool_on_modal,
80
+ inputs=[tool_params_input],
81
+ outputs=output_display,
82
+ title="Bandit Security Scanner Interface (via Modal MCP)",
83
+ description="""Interface with the Bandit security scanner tool hosted on Modal via the MCP server.
84
+ Provide Python code within a JSON structure under the 'code' key.
85
+ Ensure `MODAL_MCP_ENDPOINT` is correctly set in a .env file in the `mcp_deploy` directory or as an environment variable.
86
+ The endpoint should point to your Modal function that handles MCP tool execution (e.g., /execute_tool).""",
87
+ examples=[
88
+ [bandit_example_params]
89
+ ],
90
+ allow_flagging="never"
91
+ )
92
+
93
+ if __name__ == "__main__":
94
+ print(f"Attempting to use Modal Endpoint for Bandit: {MODAL_MCP_ENDPOINT}")
95
+ if MODAL_MCP_ENDPOINT == "YOUR_MODAL_MCP_ENDPOINT_HERE" or not MODAL_MCP_ENDPOINT:
96
+ print("\nWARNING: MODAL_MCP_ENDPOINT is not configured. The app will show an error on submit.")
97
+ print("Please create a .env file in the 'mcp_deploy' directory with:")
98
+ print("MODAL_MCP_ENDPOINT=\"your_actual_modal_mcp_endpoint_url\"\n")
99
+ iface.launch(server_name="0.0.0.0") # mcp_server=True removed as it's not needed for this direct app