11import os
2- import re
32import json
43import secrets
54import asyncio
65import subprocess
76from contextlib import asynccontextmanager
87from pathlib import Path # Import Path
98from typing import Annotated , List , Set
10- from datetime import datetime , timezone , timedelta
9+ from datetime import datetime , timezone
1110
1211from fastapi import (
1312 FastAPI ,
2524from fastapi .templating import Jinja2Templates
2625from itsdangerous import URLSafeTimedSerializer , SignatureExpired , BadSignature
2726from dotenv import load_dotenv
28- import subprocess # Added for nginx reload
2927import logging
3028
3129# --- MCP Client Imports --- START
@@ -506,13 +504,17 @@ async def get_tools_from_server(base_url: str) -> List[dict] | None: # Return li
506504 current_section = "args"
507505 section_content = [stripped_line [len ("Args:" ):].strip ()]
508506 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 ()
511511 current_section = "returns"
512512 section_content = [stripped_line [len ("Returns:" ):].strip ()]
513513 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 ()
516518 current_section = "raises"
517519 section_content = [stripped_line [len ("Raises:" ):].strip ()]
518520 elif current_section == "main" :
@@ -678,7 +680,7 @@ async def perform_single_health_check(path: str) -> tuple[str, datetime | None]:
678680
679681 except asyncio .TimeoutError :
680682 # 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"
682684 logger .info (f"Health check asyncio.wait_for timeout for { path } ({ url } )" )
683685 except FileNotFoundError :
684686 current_status = "error: command not found"
@@ -1143,7 +1145,7 @@ async def register_service(
11431145 license_str : Annotated [str , Form (alias = "license" )] = "N/A" ,
11441146 username : Annotated [str , Depends (api_auth )] = None ,
11451147):
1146- logger .info (f "[DEBUG] register_service() called with parameters:" )
1148+ logger .info ("[DEBUG] register_service() called with parameters:" )
11471149 logger .info (f"[DEBUG] - name: { name } " )
11481150 logger .info (f"[DEBUG] - description: { description } " )
11491151 logger .info (f"[DEBUG] - path: { path } " )
@@ -1188,35 +1190,35 @@ async def register_service(
11881190 logger .info (f"[DEBUG] Created server entry: { json .dumps (server_entry , indent = 2 )} " )
11891191
11901192 # 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..." )
11921194 success = save_server_to_file (server_entry )
11931195 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" )
11951197 return JSONResponse (
11961198 status_code = 500 , content = {"error" : "Failed to save server data" }
11971199 )
1198- logger .info (f "[DEBUG] Successfully saved server data to file" )
1200+ logger .info ("[DEBUG] Successfully saved server data to file" )
11991201
12001202 # 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..." )
12021204 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" )
12041206 MOCK_SERVICE_STATE [path ] = False
12051207 # 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'" )
12071209 SERVER_HEALTH_STATUS [path ] = "disabled" # Start disabled
12081210 SERVER_LAST_CHECK_TIME [path ] = None # No check time yet
12091211 # Ensure num_tools is present in the in-memory dict immediately
12101212 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" )
12121214 REGISTERED_SERVERS [path ]["num_tools" ] = 0
12131215
12141216 # 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..." )
12161218 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" )
12181220 else :
1219- logger .info (f "[DEBUG] Successfully regenerated Nginx configuration" )
1221+ logger .info ("[DEBUG] Successfully regenerated Nginx configuration" )
12201222
12211223 logger .info (f"[INFO] New service registered: '{ name } ' at path '{ path } ' by user '{ username } '" )
12221224
@@ -1231,10 +1233,10 @@ async def register_service(
12311233 # --- Persist the updated state after registration --- END
12321234
12331235 # 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..." )
12351237 asyncio .create_task (broadcast_health_status ())
12361238
1237- logger .info (f "[DEBUG] Registration complete, returning success response" )
1239+ logger .info ("[DEBUG] Registration complete, returning success response" )
12381240 return JSONResponse (
12391241 status_code = 201 ,
12401242 content = {
0 commit comments