1
1
import os
2
- import re
3
2
import json
4
3
import secrets
5
4
import asyncio
6
5
import subprocess
7
6
from contextlib import asynccontextmanager
8
7
from pathlib import Path # Import Path
9
8
from typing import Annotated , List , Set
10
- from datetime import datetime , timezone , timedelta
9
+ from datetime import datetime , timezone
11
10
12
11
from fastapi import (
13
12
FastAPI ,
25
24
from fastapi .templating import Jinja2Templates
26
25
from itsdangerous import URLSafeTimedSerializer , SignatureExpired , BadSignature
27
26
from dotenv import load_dotenv
28
- import subprocess # Added for nginx reload
29
27
import logging
30
28
31
29
# --- MCP Client Imports --- START
@@ -506,13 +504,17 @@ async def get_tools_from_server(base_url: str) -> List[dict] | None: # Return li
506
504
current_section = "args"
507
505
section_content = [stripped_line [len ("Args:" ):].strip ()]
508
506
elif stripped_line .startswith ("Returns:" ):
509
- if current_section != "main" : parsed_desc [current_section ] = "\n " .join (section_content ).strip ()
510
- else : parsed_desc ["main" ] = "\n " .join (main_desc_lines ).strip ()
507
+ if current_section != "main" :
508
+ parsed_desc [current_section ] = "\n " .join (section_content ).strip ()
509
+ else :
510
+ parsed_desc ["main" ] = "\n " .join (main_desc_lines ).strip ()
511
511
current_section = "returns"
512
512
section_content = [stripped_line [len ("Returns:" ):].strip ()]
513
513
elif stripped_line .startswith ("Raises:" ):
514
- if current_section != "main" : parsed_desc [current_section ] = "\n " .join (section_content ).strip ()
515
- else : parsed_desc ["main" ] = "\n " .join (main_desc_lines ).strip ()
514
+ if current_section != "main" :
515
+ parsed_desc [current_section ] = "\n " .join (section_content ).strip ()
516
+ else :
517
+ parsed_desc ["main" ] = "\n " .join (main_desc_lines ).strip ()
516
518
current_section = "raises"
517
519
section_content = [stripped_line [len ("Raises:" ):].strip ()]
518
520
elif current_section == "main" :
@@ -678,7 +680,7 @@ async def perform_single_health_check(path: str) -> tuple[str, datetime | None]:
678
680
679
681
except asyncio .TimeoutError :
680
682
# This catches timeout on asyncio.wait_for, slightly different from curl's --max-time
681
- current_status = f "error: check process timeout"
683
+ current_status = "error: check process timeout"
682
684
logger .info (f"Health check asyncio.wait_for timeout for { path } ({ url } )" )
683
685
except FileNotFoundError :
684
686
current_status = "error: command not found"
@@ -1143,7 +1145,7 @@ async def register_service(
1143
1145
license_str : Annotated [str , Form (alias = "license" )] = "N/A" ,
1144
1146
username : Annotated [str , Depends (api_auth )] = None ,
1145
1147
):
1146
- logger .info (f "[DEBUG] register_service() called with parameters:" )
1148
+ logger .info ("[DEBUG] register_service() called with parameters:" )
1147
1149
logger .info (f"[DEBUG] - name: { name } " )
1148
1150
logger .info (f"[DEBUG] - description: { description } " )
1149
1151
logger .info (f"[DEBUG] - path: { path } " )
@@ -1188,35 +1190,35 @@ async def register_service(
1188
1190
logger .info (f"[DEBUG] Created server entry: { json .dumps (server_entry , indent = 2 )} " )
1189
1191
1190
1192
# Save to individual file
1191
- logger .info (f "[DEBUG] Attempting to save server data to file..." )
1193
+ logger .info ("[DEBUG] Attempting to save server data to file..." )
1192
1194
success = save_server_to_file (server_entry )
1193
1195
if not success :
1194
- logger .error (f "[ERROR] Failed to save server data to file" )
1196
+ logger .error ("[ERROR] Failed to save server data to file" )
1195
1197
return JSONResponse (
1196
1198
status_code = 500 , content = {"error" : "Failed to save server data" }
1197
1199
)
1198
- logger .info (f "[DEBUG] Successfully saved server data to file" )
1200
+ logger .info ("[DEBUG] Successfully saved server data to file" )
1199
1201
1200
1202
# Add to in-memory registry and default to disabled
1201
- logger .info (f "[DEBUG] Adding server to in-memory registry..." )
1203
+ logger .info ("[DEBUG] Adding server to in-memory registry..." )
1202
1204
REGISTERED_SERVERS [path ] = server_entry
1203
- logger .info (f "[DEBUG] Setting initial service state to disabled" )
1205
+ logger .info ("[DEBUG] Setting initial service state to disabled" )
1204
1206
MOCK_SERVICE_STATE [path ] = False
1205
1207
# Set initial health status for the new service (always start disabled)
1206
- logger .info (f "[DEBUG] Setting initial health status to 'disabled'" )
1208
+ logger .info ("[DEBUG] Setting initial health status to 'disabled'" )
1207
1209
SERVER_HEALTH_STATUS [path ] = "disabled" # Start disabled
1208
1210
SERVER_LAST_CHECK_TIME [path ] = None # No check time yet
1209
1211
# Ensure num_tools is present in the in-memory dict immediately
1210
1212
if "num_tools" not in REGISTERED_SERVERS [path ]:
1211
- logger .info (f "[DEBUG] Adding missing num_tools field to in-memory registry" )
1213
+ logger .info ("[DEBUG] Adding missing num_tools field to in-memory registry" )
1212
1214
REGISTERED_SERVERS [path ]["num_tools" ] = 0
1213
1215
1214
1216
# Regenerate Nginx config after successful registration
1215
- logger .info (f "[DEBUG] Attempting to regenerate Nginx configuration..." )
1217
+ logger .info ("[DEBUG] Attempting to regenerate Nginx configuration..." )
1216
1218
if not regenerate_nginx_config ():
1217
- logger .error (f "[ERROR] Failed to update Nginx configuration after registration" )
1219
+ logger .error ("[ERROR] Failed to update Nginx configuration after registration" )
1218
1220
else :
1219
- logger .info (f "[DEBUG] Successfully regenerated Nginx configuration" )
1221
+ logger .info ("[DEBUG] Successfully regenerated Nginx configuration" )
1220
1222
1221
1223
logger .info (f"[INFO] New service registered: '{ name } ' at path '{ path } ' by user '{ username } '" )
1222
1224
@@ -1231,10 +1233,10 @@ async def register_service(
1231
1233
# --- Persist the updated state after registration --- END
1232
1234
1233
1235
# Broadcast the updated status after registration
1234
- logger .info (f "[DEBUG] Creating task to broadcast health status..." )
1236
+ logger .info ("[DEBUG] Creating task to broadcast health status..." )
1235
1237
asyncio .create_task (broadcast_health_status ())
1236
1238
1237
- logger .info (f "[DEBUG] Registration complete, returning success response" )
1239
+ logger .info ("[DEBUG] Registration complete, returning success response" )
1238
1240
return JSONResponse (
1239
1241
status_code = 201 ,
1240
1242
content = {
0 commit comments