更新 server.py

This commit is contained in:
2025-04-17 00:22:07 +08:00
parent 1f23898258
commit a0c6503644

159
server.py
View File

@@ -2,8 +2,8 @@
# -*- coding: utf-8 -*-
"""
Maya MCP Server
Core implementation of the Model Context Protocol server for Maya.
Maya MCP Server (FastAPI Implementation)
Core implementation of the Model Context Protocol server for Maya using FastAPI.
Version: 1.0.0
Author: Jeffrey Tsai
@@ -23,13 +23,47 @@ from log_config import get_logger, initialize_logging
initialize_logging()
logger = get_logger("Server")
# Import HTTP handler
# Try to import FastAPI server, fall back to HTTP handler if not available
USE_FASTAPI = False # Default to False
try:
from http_handler import start_http_server, stop_http_server, is_http_server_running, broadcast_event
logger.info("HTTP handler imported successfully")
except Exception as e:
logger.error(f"Error importing HTTP handler: {e}")
from fastapi_server import start_server as fastapi_start_server
from fastapi_server import stop_server as fastapi_stop_server
from fastapi_server import is_server_running as fastapi_is_server_running
from fastapi_server import broadcast_event_sync as fastapi_broadcast_event_sync
logger.info("FastAPI server imported successfully")
# Check if FastAPI is actually working by trying to create a simple app
try:
import fastapi
test_app = fastapi.FastAPI()
logger.info("FastAPI test successful")
USE_FASTAPI = True
except Exception as e:
logger.error(f"FastAPI test failed: {str(e)}")
logger.info("HTTP handler imported as fallback")
USE_FASTAPI = False
except ImportError as e:
logger.error(f"Error importing FastAPI server: {str(e)}")
logger.error(traceback.format_exc())
logger.info("HTTP handler imported as fallback")
USE_FASTAPI = False
# Fallback to HTTP handler if FastAPI is not available
try:
from http_handler import start_http_server, stop_http_server, is_http_server_running, broadcast_event
logger.info("HTTP handler imported as fallback")
# Set flags to indicate we're using the fallback
_using_fastapi = False
except Exception as e2:
logger.error(f"Error importing HTTP handler: {e2}")
logger.error(traceback.format_exc())
else:
# Set flags to indicate we're using FastAPI
_using_fastapi = True
# Alias the functions for compatibility
start_http_server = fastapi_start_server
stop_http_server = fastapi_stop_server
is_http_server_running = fastapi_is_server_running
broadcast_event = fastapi_broadcast_event_sync
# Global variables
_server_running = False
@@ -45,51 +79,82 @@ def start_server(port=SERVER_PORT):
Returns:
int: Port number if server started successfully, None otherwise
"""
global SERVER_PORT, _server_running
global _server_running, USE_FASTAPI
try:
# Check if server is already running
if _server_running:
logger.info(f"Server already running on port {SERVER_PORT}")
return SERVER_PORT
if is_server_running():
logger.info(f"Server already running on port {port}")
return port
logger.info(f"Starting MCP server on port {port}...")
# Start HTTP server
http_port = start_http_server(port)
if http_port:
_server_running = True
SERVER_PORT = http_port
logger.info(f"MCP server successfully started on port {SERVER_PORT}")
# Get Maya info
# Start the server based on available implementation
if USE_FASTAPI:
try:
# Try to start FastAPI server
port = fastapi_start_server(port=port)
if port:
_server_running = True
# Log Maya info
maya_info = {
'maya_version': cmds.about(version=True),
'maya_api_version': om.MGlobal.apiVersion(),
'os_name': cmds.about(os=True),
'product_name': cmds.about(product=True)
}
logger.info(f"Maya info: {maya_info}")
try:
# Broadcast Maya info to clients
fastapi_broadcast_event_sync("maya_info", maya_info)
except Exception as e:
logger.error(f"Error broadcasting event: {str(e)}")
# This is not a critical error, so we can continue
logger.info(f"MCP server successfully started on port {port}")
print("\n==================================================")
print(f"MCP SERVER STARTED SUCCESSFULLY ON PORT {port}")
print("==================================================\n")
return port
else:
logger.error("Failed to start FastAPI server")
# Fall back to HTTP handler
logger.info("Falling back to HTTP handler")
USE_FASTAPI = False
except Exception as e:
logger.error(f"Error starting FastAPI server: {str(e)}")
logger.error(traceback.format_exc())
# Fall back to HTTP handler
logger.info("Falling back to HTTP handler")
USE_FASTAPI = False
# If FastAPI failed or not available, use HTTP handler
if not USE_FASTAPI:
from http_handler import start_http_server, stop_http_server, is_http_server_running, broadcast_event
port = start_http_server(port=port)
if port:
_server_running = True
# Log Maya info
maya_info = {
"maya_version": cmds.about(version=True),
"maya_api_version": om.MGlobal.apiVersion(),
"os_name": cmds.about(operatingSystem=True),
"product_name": cmds.about(product=True)
'maya_version': cmds.about(version=True),
'maya_api_version': om.MGlobal.apiVersion(),
'os_name': cmds.about(os=True),
'product_name': cmds.about(product=True)
}
logger.info(f"Maya info: {maya_info}")
# Broadcast Maya info event
try:
broadcast_event("maya_info", maya_info)
logger.debug("Maya info event broadcasted")
except Exception as e:
logger.warning(f"Error broadcasting Maya info: {e}")
logger.debug(traceback.format_exc())
except Exception as e:
logger.warning(f"Error getting Maya info: {e}")
logger.debug(traceback.format_exc())
return SERVER_PORT
else:
logger.error(f"Failed to start HTTP server on port {port}")
return None
# Broadcast Maya info to clients
broadcast_event("maya_info", maya_info)
logger.info(f"MCP server successfully started on port {port}")
print("\n==================================================")
print(f"MCP SERVER STARTED SUCCESSFULLY ON PORT {port}")
print("==================================================\n")
return port
else:
logger.error("Failed to start HTTP server")
return None
except Exception as e:
logger.error(f"Error starting server: {e}")
logger.error(traceback.format_exc())
@@ -208,14 +273,20 @@ def get_scene_info():
scene_info = {
"file": current_file,
"selection": selection,
"objects": objects[:10], # Limit to first 10
"objects": objects,
"cameras": cameras,
"lights": lights
}
logger.debug(f"Scene info retrieved: {len(str(scene_info))} bytes")
logger.debug(f"Scene info: {scene_info}")
return scene_info
except Exception as e:
logger.error(f"Error getting scene info: {e}")
logger.error(traceback.format_exc())
return {"error": str(e)}
return {
"file": "unknown",
"selection": [],
"objects": [],
"cameras": [],
"lights": []
}