Googolplexic commited on
Commit
1e513bd
·
1 Parent(s): 6ef2f10

Refactor API call to be for validation;

Browse files
Files changed (3) hide show
  1. apiCall.py +28 -28
  2. api_validator.py +248 -0
  3. main.py +66 -41
apiCall.py CHANGED
@@ -23,37 +23,37 @@ def api_call(
23
  Examples:
24
 
25
  1. Simple GET request to a search API:
26
- method: "GET"
27
- base_url: "https://v2.xivapi.com/api"
28
- endpoint: "search"
29
- param_keys_values:
30
- query: Name~"popoto"
31
- sheets: Item
32
- fields: Name,Description
33
- language: en
34
- limit: 1
35
 
36
  2. GitHub API request with headers:
37
- method: "GET"
38
- base_url: "https://api.github.com"
39
- endpoint: "repos/microsoft/TypeScript/issues"
40
- param_keys_values:
41
- state: open
42
- per_page: 5
43
- header_keys_values:
44
- Accept: application/vnd.github.v3+json
45
 
46
  3. POST request with JSON body. the "messages" parameter is complexly structured, so it requires special handling."
47
- method: "POST"
48
- base_url: "https://api.anthropic.com"
49
- endpoint: "v1/messages"
50
- param_keys_values:
51
- model: claude-opus-4-20250514
52
- max_tokens: 1024
53
- header_keys_values:
54
- x-api-key: your_api_key_here
55
- content-type: application/json
56
- additional_params: {"messages": [{"role": "user", "content": "Hello there!"}]}
57
  """
58
  # Build params dictionary from key-value pairs
59
  params = {}
@@ -110,7 +110,7 @@ def api_call(
110
  params=params,
111
  headers=headers,
112
  method=method,
113
- )
114
  return result
115
  except Exception as e:
116
  return f"Error making API call: {str(e)}"
 
23
  Examples:
24
 
25
  1. Simple GET request to a search API:
26
+ method: "GET"
27
+ base_url: "https://v2.xivapi.com/api"
28
+ endpoint: "search"
29
+ param_keys_values:
30
+ query: Name~"popoto"
31
+ sheets: Item
32
+ fields: Name,Description
33
+ language: en
34
+ limit: 1
35
 
36
  2. GitHub API request with headers:
37
+ method: "GET"
38
+ base_url: "https://api.github.com"
39
+ endpoint: "repos/microsoft/TypeScript/issues"
40
+ param_keys_values:
41
+ state: open
42
+ per_page: 5
43
+ header_keys_values:
44
+ Accept: application/vnd.github.v3+json
45
 
46
  3. POST request with JSON body. the "messages" parameter is complexly structured, so it requires special handling."
47
+ method: "POST"
48
+ base_url: "https://api.anthropic.com"
49
+ endpoint: "v1/messages"
50
+ param_keys_values:
51
+ model: claude-opus-4-20250514
52
+ max_tokens: 1024
53
+ header_keys_values:
54
+ x-api-key: your_api_key_here
55
+ content-type: application/json
56
+ additional_params: {"messages": [{"role": "user", "content": "Hello there!"}]}
57
  """
58
  # Build params dictionary from key-value pairs
59
  params = {}
 
110
  params=params,
111
  headers=headers,
112
  method=method,
113
+ )
114
  return result
115
  except Exception as e:
116
  return f"Error making API call: {str(e)}"
api_validator.py ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import apiCall
2
+ import json
3
+ import os
4
+ from datetime import datetime, timedelta
5
+ import hashlib
6
+
7
+
8
+ def validate_api_call(
9
+ mcp_api_key,
10
+ name,
11
+ description,
12
+ method,
13
+ base_url,
14
+ endpoint,
15
+ param_keys_values,
16
+ header_keys_values,
17
+ additional_params,
18
+ schedule_interval_minutes,
19
+ stop_after_hours,
20
+ start_time,
21
+ ):
22
+ """
23
+ Validate API call parameters and store successful configuration.
24
+
25
+ Parameters:
26
+ - mcp_api_key: MCP API key serves as user identifier
27
+ - name: User-friendly name for the monitoring task
28
+ - description: Description of what is being monitored
29
+ - method: HTTP method (GET, POST, PUT, DELETE)
30
+ - base_url: The base URL of the API
31
+ - endpoint: The specific API endpoint
32
+ - param_keys_values: Parameter key-value pairs, one per line
33
+ - header_keys_values: Header key-value pairs, one per line
34
+ - additional_params: Optional JSON string for complex parameters
35
+ - schedule_interval_minutes: Minutes between calls
36
+ - stop_after_hours: Hours after which to stop (max 168 = 1 week)
37
+ - start_time: When to start the monitoring (datetime string or None for immediate)
38
+
39
+ Returns:
40
+ - Dictionary with success status, config_id, message, and sample_response
41
+
42
+ Example return:
43
+ {
44
+ "success": True,
45
+ "config_id": 123,
46
+ "message": "API call validated and stored successfully",
47
+ "sample_response": {...},
48
+ "stop_at": "2025-06-11T12:00:00Z",
49
+ "start_at": "2025-06-04T12:00:00Z"
50
+ }
51
+ """
52
+ try:
53
+ # Validate input parameters
54
+ if not mcp_api_key or not mcp_api_key.strip():
55
+ return {
56
+ "success": False,
57
+ "message": "MCP API key is required",
58
+ "config_id": None,
59
+ }
60
+
61
+ if not name or not name.strip():
62
+ return {
63
+ "success": False,
64
+ "message": "Monitoring name is required",
65
+ "config_id": None,
66
+ }
67
+
68
+ if not base_url or not base_url.strip():
69
+ return {
70
+ "success": False,
71
+ "message": "Base URL is required",
72
+ "config_id": None,
73
+ }
74
+
75
+ if not method or method not in ["GET", "POST", "PUT", "DELETE"]:
76
+ return {
77
+ "success": False,
78
+ "message": "Valid HTTP method is required (GET, POST, PUT, DELETE)",
79
+ "config_id": None,
80
+ }
81
+
82
+ if (
83
+ not isinstance(schedule_interval_minutes, (int, float))
84
+ or schedule_interval_minutes < 1
85
+ or schedule_interval_minutes > 1440
86
+ ):
87
+ return {
88
+ "success": False,
89
+ "message": "Schedule interval must be between 1 and 1440 minutes",
90
+ "config_id": None,
91
+ }
92
+
93
+ if (
94
+ not isinstance(stop_after_hours, (int, float))
95
+ or stop_after_hours < 1
96
+ or stop_after_hours > 168
97
+ ):
98
+ return {
99
+ "success": False,
100
+ "message": "Stop after hours must be between 1 and 168 hours (1 week max)",
101
+ "config_id": None,
102
+ }
103
+
104
+ # Validate start_time if provided
105
+ if start_time:
106
+ try:
107
+ start_datetime = datetime.fromisoformat(
108
+ start_time.replace("Z", "+00:00")
109
+ )
110
+ if start_datetime < datetime.now():
111
+ return {
112
+ "success": False,
113
+ "message": "Start time cannot be in the past",
114
+ "config_id": None,
115
+ }
116
+ except ValueError:
117
+ return {
118
+ "success": False,
119
+ "message": "Invalid start time format",
120
+ "config_id": None,
121
+ }
122
+ else:
123
+ start_datetime = datetime.now()
124
+
125
+ # Test the API call
126
+ result = apiCall.api_call(
127
+ method=method,
128
+ base_url=base_url,
129
+ endpoint=endpoint,
130
+ param_keys_values=param_keys_values,
131
+ header_keys_values=header_keys_values,
132
+ additional_params=additional_params,
133
+ )
134
+
135
+ # Check if the API call failed
136
+ if isinstance(result, str) and result.startswith("Error"):
137
+ return {
138
+ "success": False,
139
+ "message": f"API call test failed: {result}",
140
+ "config_id": None,
141
+ }
142
+
143
+ # Generate config ID and calculate timestamps
144
+ config_data = {
145
+ "mcp_api_key": mcp_api_key,
146
+ "name": name,
147
+ "description": description,
148
+ "method": method,
149
+ "base_url": base_url,
150
+ "endpoint": endpoint,
151
+ "param_keys_values": param_keys_values,
152
+ "header_keys_values": header_keys_values,
153
+ "additional_params": additional_params,
154
+ "schedule_interval_minutes": schedule_interval_minutes,
155
+ "stop_after_hours": stop_after_hours,
156
+ "start_time": start_time,
157
+ }
158
+
159
+ # Generate unique config ID
160
+ config_str = json.dumps(config_data, sort_keys=True)
161
+ config_id = int(hashlib.md5(config_str.encode()).hexdigest()[:8], 16)
162
+
163
+ # Calculate timestamps
164
+ created_at = datetime.now()
165
+ stop_at = start_datetime + timedelta(hours=stop_after_hours)
166
+
167
+ # Add metadata to config
168
+ config_data.update(
169
+ {
170
+ "config_id": config_id,
171
+ "created_at": created_at.isoformat(),
172
+ "start_at": start_datetime.isoformat(),
173
+ "stop_at": stop_at.isoformat(),
174
+
175
+ # @JamezyKim This will be used to track the status of whether the api is confirmed or not
176
+ "is_validated": False,
177
+ "sample_response": result,
178
+ }
179
+ )
180
+
181
+ # Store configuration
182
+ # TODO: Implement database
183
+
184
+ # Return success response
185
+ return {
186
+ "success": True,
187
+ "config_id": config_id,
188
+ "message": f"API call validated and stored successfully for '{name}'",
189
+ "sample_response": result,
190
+ "start_at": start_datetime.isoformat(),
191
+ "stop_at": stop_at.isoformat(),
192
+ "schedule_interval_minutes": schedule_interval_minutes,
193
+ }
194
+
195
+ except Exception as e:
196
+ return {
197
+ "success": False,
198
+ "message": f"Validation failed with error: {str(e)}",
199
+ "config_id": None,
200
+ }
201
+
202
+
203
+ def setup_scheduler(config_id, mcp_api_key):
204
+ """
205
+ Set up periodic calling for a validated API configuration.
206
+
207
+ Parameters:
208
+ - config_id: The ID from validated configuration
209
+ - mcp_api_key: User's MCP API key for verification
210
+
211
+ Returns:
212
+ - Dictionary with success status and scheduling details
213
+
214
+ Example return:
215
+ {
216
+ "success": True,
217
+ "message": "Scheduler activated for 'NVDA Stock Price'",
218
+ "config_id": 123,
219
+ "schedule_interval_minutes": 20,
220
+ "stop_at": "2025-06-11T12:00:00Z",
221
+ "next_call_at": "2025-06-04T12:20:00Z"
222
+ }
223
+ """
224
+
225
+ return {
226
+ "success": False,
227
+ "message": "Function not implemented yet",
228
+ "config_id": config_id,
229
+ }
230
+
231
+
232
+ if __name__ == "__main__":
233
+ # Example usage
234
+ response = validate_api_call(
235
+ mcp_api_key="your_api_key",
236
+ name="NVDA Stock Price",
237
+ description="Monitor the stock price of NVIDIA",
238
+ method="GET",
239
+ base_url="https://api.example.com",
240
+ endpoint="stocks/NVDA",
241
+ param_keys_values="",
242
+ header_keys_values="",
243
+ additional_params="{}",
244
+ schedule_interval_minutes=20,
245
+ stop_after_hours=24,
246
+ start_time=None,
247
+ )
248
+ print(response)
main.py CHANGED
@@ -1,67 +1,92 @@
1
  import gradio as gr
2
  from apiCall import api_call
 
3
 
4
 
5
- demo = gr.Interface(
6
- fn=api_call,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  inputs=[
8
- gr.Radio(choices=["GET", "POST", "PUT", "DELETE"], label="Method", value="GET"),
9
  gr.Textbox(
10
- label="Base URL",
11
- placeholder="Enter base URL",
12
- value="https://v2.xivapi.com/api",
 
 
 
 
 
 
 
13
  ),
14
- gr.Textbox(label="Endpoint", placeholder="Enter endpoint", value="search"),
 
 
15
  gr.Textbox(
16
  label="Parameter Key-Value Pairs",
17
  placeholder="Enter one parameter per line in format 'key: value'",
18
- value='query: Name~"popoto"\nsheets: Item\nfields: Name,Description\nlanguage: en\nlimit: 1',
19
- lines=5,
20
  ),
21
  gr.Textbox(
22
  label="Header Key-Value Pairs",
23
  placeholder="Enter one header per line in format 'key: value'",
24
  value="",
25
- lines=3,
26
  ),
27
  gr.Textbox(
28
  label="Additional Parameters (JSON)",
29
  placeholder="Enter any additional parameters as JSON",
30
  value="{}",
31
- lines=3,
 
 
 
 
 
 
 
 
32
  ),
33
  ],
34
- outputs=gr.Textbox(label="API Response", lines=10),
35
- title="Universal API Client",
36
- description="Make API calls to any endpoint with custom parameters and headers. \n\n- **Method**: Choose the appropriate HTTP method for your request \n- **Base URL**: Enter the full API base URL (e.g., 'https://api.example.com') \n- **Endpoint**: The specific endpoint to call (without leading slash) \n- **Parameter Key-Value Pairs**: Format as 'key: value' with each pair on a new line \n Example: \n```\nquery: search term\nlimit: 10\nfilter: active\n``` \n- **Header Key-Value Pairs**: Format as 'key: value' with each pair on a new line \n Example: \n```\nx-api-key: your_api_key\ncontent-type: application/json\n``` \n- **Additional Parameters**: Use valid JSON format for nested or complex parameters",
37
- flagging_mode="manual",
38
- flagging_options=["Invalid Request", "API Error", "Other"],
39
- examples=[
40
- [
41
- "GET",
42
- "https://v2.xivapi.com/api",
43
- "search",
44
- 'query: Name~"popoto"\nsheets: Item\nfields: Name,Description\nlanguage: en\nlimit: 1',
45
- "",
46
- "{}",
47
- ],
48
- [
49
- "GET",
50
- "https://api.github.com",
51
- "repos/microsoft/TypeScript/issues",
52
- "state: open\nper_page: 5",
53
- "Accept: application/vnd.github.v3+json",
54
- "{}",
55
- ],
56
- [
57
- "POST",
58
- "https://api.anthropic.com",
59
- "v1/messages",
60
- "model: claude-opus-4-20250514\nmax_tokens: 1024",
61
- "x-api-key: your_api_key_here\nanthropic-version: 2023-06-01\ncontent-type: application/json",
62
- '{"messages": [{"role": "user", "content": "Hello there!"}]}',
63
- ],
64
  ],
 
 
 
 
 
 
 
 
 
 
65
  )
66
 
67
  if __name__ == "__main__":
 
1
  import gradio as gr
2
  from apiCall import api_call
3
+ from api_validator import validate_api_call, setup_scheduler
4
 
5
 
6
+ def format_validation_result(result):
7
+ """Format validation result for display"""
8
+ if result["success"]:
9
+ return f"✅ Success!\n\nConfig ID: {result['config_id']}\nMessage: {result['message']}\n\nSample Response:\n{result.get('sample_response', 'No sample response')}"
10
+ else:
11
+ return f"❌ Failed!\n\nMessage: {result['message']}"
12
+
13
+
14
+ def format_scheduler_result(result):
15
+ """Format scheduler result for display"""
16
+ if result["success"]:
17
+ return f"✅ Scheduler Active!\n\nConfig ID: {result['config_id']}\nMessage: {result['message']}\n\nSchedule Details:\n{result.get('schedule_interval_minutes', 'N/A')} minutes interval\nStops at: {result.get('stop_at', 'N/A')}"
18
+ else:
19
+ return f"❌ Scheduler Failed!\n\nMessage: {result['message']}"
20
+
21
+
22
+ # API Validation Tab
23
+ validation_tab = gr.Interface(
24
+ fn=lambda *args: format_validation_result(validate_api_call(*args)),
25
  inputs=[
 
26
  gr.Textbox(
27
+ label="MCP API Key", placeholder="Enter your MCP API key", type="password"
28
+ ),
29
+ gr.Textbox(
30
+ label="Monitoring Name", placeholder="e.g., 'NVDA Stock Price'", value=""
31
+ ),
32
+ gr.Textbox(
33
+ label="Description",
34
+ placeholder="What are you monitoring?",
35
+ value="",
36
+ lines=2,
37
  ),
38
+ gr.Radio(choices=["GET", "POST", "PUT", "DELETE"], label="Method", value="GET"),
39
+ gr.Textbox(label="Base URL", placeholder="https://api.example.com", value=""),
40
+ gr.Textbox(label="Endpoint", placeholder="endpoint/path", value=""),
41
  gr.Textbox(
42
  label="Parameter Key-Value Pairs",
43
  placeholder="Enter one parameter per line in format 'key: value'",
44
+ value="",
 
45
  ),
46
  gr.Textbox(
47
  label="Header Key-Value Pairs",
48
  placeholder="Enter one header per line in format 'key: value'",
49
  value="",
 
50
  ),
51
  gr.Textbox(
52
  label="Additional Parameters (JSON)",
53
  placeholder="Enter any additional parameters as JSON",
54
  value="{}",
55
+ ),
56
+ gr.Number(
57
+ label="Schedule Interval (minutes)", value=20, minimum=1, maximum=1440
58
+ ),
59
+ gr.Number(label="Stop After (hours)", value=24, minimum=1, maximum=168),
60
+ gr.Textbox(
61
+ label="Start Time (optional)",
62
+ placeholder="YYYY-MM-DD HH:MM:SS or leave empty for immediate start",
63
+ value="",
64
  ),
65
  ],
66
+ outputs=gr.Textbox(label="Validation Result", lines=10),
67
+ title="API Validation & Storage",
68
+ description="Validate your API configuration and store it for scheduled monitoring. Max monitoring period is 1 week (168 hours).",
69
+ )
70
+
71
+ # Scheduler Setup Tab
72
+ scheduler_tab = gr.Interface(
73
+ fn=lambda *args: format_scheduler_result(setup_scheduler(*args)),
74
+ inputs=[
75
+ gr.Number(label="Config ID (from validation step)", value=None),
76
+ gr.Textbox(
77
+ label="MCP API Key", placeholder="Enter your MCP API key", type="password"
78
+ ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  ],
80
+ outputs=gr.Textbox(label="Scheduler Result", lines=8),
81
+ title="Scheduler Setup",
82
+ description="Activate scheduled monitoring for a validated API configuration.",
83
+ )
84
+
85
+ # Create tabbed interface
86
+ demo = gr.TabbedInterface(
87
+ [validation_tab, scheduler_tab],
88
+ ["Validate & Store", "Activate Scheduler"],
89
+ title="MCP API Monitoring System",
90
  )
91
 
92
  if __name__ == "__main__":