[feat] Refactor configuration management and fix default host (#41)
This PR refactors the configuration management to unify the handling of command-line arguments, environment variables, and default settings. Key changes: - All configuration is now consistently managed through the `DorisConfig` object. - Command-line arguments now correctly override environment variables and default settings. - The default server host/port is now correctly read from the configuration. - Wrong environment variable loading in `schema_extractor.py` has been removed. closes #37
This commit is contained in:
@@ -637,12 +637,15 @@ Examples:
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--host",
|
"--host",
|
||||||
type=str,
|
type=str,
|
||||||
default=os.getenv("SERVER_HOST", _default_config.database.host),
|
default=os.getenv("SERVER_HOST", _default_config.server_host),
|
||||||
help=f"Host address for HTTP mode (default: {_default_config.database.host})",
|
help=f"Host address for HTTP mode (default: {_default_config.server_host})",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--port", type=int, default=os.getenv("SERVER_PORT", _default_config.server_port), help=f"Port number for HTTP mode (default: {_default_config.server_port})"
|
"--port",
|
||||||
|
type=int,
|
||||||
|
default=os.getenv("SERVER_PORT", _default_config.server_port),
|
||||||
|
help=f"Port number for HTTP mode (default: {_default_config.server_port})"
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@@ -680,18 +683,29 @@ Examples:
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
async def main():
|
def update_configuration(config: DorisConfig):
|
||||||
"""Main function"""
|
"""Update doris configuration object"""
|
||||||
|
# For some arguments, if not specified, environment variables or default configurations will be used as default values
|
||||||
parser = create_arg_parser()
|
parser = create_arg_parser()
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Create configuration - priority: command line arguments > .env file > default values
|
# Update config values
|
||||||
config = DorisConfig.from_env() # First load from .env file and environment variables
|
|
||||||
|
|
||||||
# Command line arguments override configuration (if provided)
|
# Command line arguments override configuration (if provided)
|
||||||
# 🔧 FIX: Set transport from command line arguments
|
# basic
|
||||||
config.transport = args.transport
|
if args.transport != _default_config.transport:
|
||||||
|
config.transport = args.transport
|
||||||
|
if args.host != _default_config.server_host:
|
||||||
|
config.server_host = args.host
|
||||||
|
if args.port != _default_config.server_port:
|
||||||
|
config.server_port = args.port
|
||||||
|
server_name = os.getenv("SERVER_NAME")
|
||||||
|
if server_name:
|
||||||
|
config.server_name = server_name
|
||||||
|
server_version = os.getenv("SERVER_VERSION")
|
||||||
|
if server_version:
|
||||||
|
config.server_version = server_version
|
||||||
|
|
||||||
|
# database
|
||||||
if args.doris_host != _default_config.database.host: # If not default value, use command line argument
|
if args.doris_host != _default_config.database.host: # If not default value, use command line argument
|
||||||
config.database.host = args.doris_host
|
config.database.host = args.doris_host
|
||||||
if args.doris_port != _default_config.database.port:
|
if args.doris_port != _default_config.database.port:
|
||||||
@@ -702,9 +716,21 @@ async def main():
|
|||||||
config.database.password = args.doris_password
|
config.database.password = args.doris_password
|
||||||
if args.doris_database != _default_config.database.database:
|
if args.doris_database != _default_config.database.database:
|
||||||
config.database.database = args.doris_database
|
config.database.database = args.doris_database
|
||||||
|
|
||||||
|
# logging
|
||||||
if args.log_level != _default_config.logging.level:
|
if args.log_level != _default_config.logging.level:
|
||||||
config.logging.level = args.log_level
|
config.logging.level = args.log_level
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
"""Main function"""
|
||||||
|
# Create configuration - priority: command line arguments > env variables > .env file > default values
|
||||||
|
# First load from .env file and environment variables
|
||||||
|
config = DorisConfig.from_env()
|
||||||
|
|
||||||
|
# Then parse the command line arguments, and update the config object.
|
||||||
|
update_configuration(config)
|
||||||
|
|
||||||
# Initialize enhanced logging system
|
# Initialize enhanced logging system
|
||||||
from .utils.config import ConfigManager
|
from .utils.config import ConfigManager
|
||||||
config_manager = ConfigManager(config)
|
config_manager = ConfigManager(config)
|
||||||
@@ -718,17 +744,17 @@ async def main():
|
|||||||
log_system_info()
|
log_system_info()
|
||||||
|
|
||||||
logger.info("Starting Doris MCP Server...")
|
logger.info("Starting Doris MCP Server...")
|
||||||
logger.info(f"Transport: {args.transport}")
|
logger.info(f"Transport: {config.transport}")
|
||||||
logger.info(f"Log Level: {config.logging.level}")
|
logger.info(f"Log Level: {config.logging.level}")
|
||||||
|
|
||||||
# Create server instance
|
# Create server instance
|
||||||
server = DorisServer(config)
|
server = DorisServer(config)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if args.transport == "stdio":
|
if config.transport == "stdio":
|
||||||
await server.start_stdio()
|
await server.start_stdio()
|
||||||
elif args.transport == "http":
|
elif config.transport == "http":
|
||||||
await server.start_http(args.host, args.port)
|
await server.start_http(config.server_host, config.server_port)
|
||||||
else:
|
else:
|
||||||
logger.error(f"Unsupported transport protocol: {args.transport}")
|
logger.error(f"Unsupported transport protocol: {args.transport}")
|
||||||
await server.shutdown()
|
await server.shutdown()
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ class DorisConfig:
|
|||||||
# Basic configuration
|
# Basic configuration
|
||||||
server_name: str = "doris-mcp-server"
|
server_name: str = "doris-mcp-server"
|
||||||
server_version: str = "0.4.1"
|
server_version: str = "0.4.1"
|
||||||
|
server_host: str = "localhost"
|
||||||
server_port: int = 3000
|
server_port: int = 3000
|
||||||
transport: str = "stdio"
|
transport: str = "stdio"
|
||||||
|
|
||||||
@@ -267,6 +268,9 @@ class DorisConfig:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_env(cls, env_file: str | None = None) -> "DorisConfig":
|
def from_env(cls, env_file: str | None = None) -> "DorisConfig":
|
||||||
"""Load configuration from environment variables
|
"""Load configuration from environment variables
|
||||||
|
|
||||||
|
The kv pairs in the. env file will be loaded as environment variables,
|
||||||
|
but the existing environment variables will not be overridden.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
env_file: .env file path, if None, search in the following order:
|
env_file: .env file path, if None, search in the following order:
|
||||||
@@ -286,7 +290,7 @@ class DorisConfig:
|
|||||||
env_files = [".env", ".env.local", ".env.production", ".env.development"]
|
env_files = [".env", ".env.local", ".env.production", ".env.development"]
|
||||||
for env_path in env_files:
|
for env_path in env_files:
|
||||||
if Path(env_path).exists():
|
if Path(env_path).exists():
|
||||||
load_dotenv(env_path)
|
load_dotenv(env_path, override=False)
|
||||||
logging.getLogger(__name__).info(f"Loaded environment configuration file: {env_path}")
|
logging.getLogger(__name__).info(f"Loaded environment configuration file: {env_path}")
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -36,9 +36,6 @@ from .logger import get_logger
|
|||||||
# Configure logging
|
# Configure logging
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
# Load environment variables
|
|
||||||
load_dotenv(override=True)
|
|
||||||
|
|
||||||
METADATA_DB_NAME="information_schema"
|
METADATA_DB_NAME="information_schema"
|
||||||
ENABLE_MULTI_DATABASE=os.getenv("ENABLE_MULTI_DATABASE",True)
|
ENABLE_MULTI_DATABASE=os.getenv("ENABLE_MULTI_DATABASE",True)
|
||||||
MULTI_DATABASE_NAMES=os.getenv("MULTI_DATABASE_NAMES","")
|
MULTI_DATABASE_NAMES=os.getenv("MULTI_DATABASE_NAMES","")
|
||||||
@@ -1656,4 +1653,4 @@ class MetadataManager:
|
|||||||
|
|
||||||
async def get_catalog_list(self) -> Dict[str, Any]:
|
async def get_catalog_list(self) -> Dict[str, Any]:
|
||||||
"""Get Doris catalog list"""
|
"""Get Doris catalog list"""
|
||||||
return await self.extractor.get_catalog_list_for_mcp()
|
return await self.extractor.get_catalog_list_for_mcp()
|
||||||
|
|||||||
Reference in New Issue
Block a user