From 7865e747e757c76212e022b66937193fe3e9f5c4 Mon Sep 17 00:00:00 2001 From: TerminalMan <84923604+SecretiveShell@users.noreply.github.com> Date: Fri, 31 Jan 2025 21:00:07 +0000 Subject: [PATCH] add native envsubst --- mcp_bridge/config/__init__.py | 3 +++ mcp_bridge/config/env_subst.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 mcp_bridge/config/env_subst.py diff --git a/mcp_bridge/config/__init__.py b/mcp_bridge/config/__init__.py index 8e7c7ed..17e5517 100644 --- a/mcp_bridge/config/__init__.py +++ b/mcp_bridge/config/__init__.py @@ -1,3 +1,4 @@ +from mcp_bridge.config.env_subst import substitute_env_vars from mcp_bridge.config.initial import initial_settings from mcp_bridge.config.final import Settings from typing import Any, Callable @@ -38,6 +39,8 @@ for cfg in configs: always_merger.merge(result, cfg) + result = substitute_env_vars(result) + # build the config try: config = Settings(**result) diff --git a/mcp_bridge/config/env_subst.py b/mcp_bridge/config/env_subst.py new file mode 100644 index 0000000..7f6b9e3 --- /dev/null +++ b/mcp_bridge/config/env_subst.py @@ -0,0 +1,31 @@ +from string import Template +from typing import Any +import os + +from loguru import logger + + +def substitute_env_vars(config: Any, env: dict[str, str] | None = None) -> Any: + """Substitute environment variables in a configuration object.""" + + # copy the environment if it is not provided + if env is None: + env = os.environ.copy() + + assert env is not None, "env is None" # the guard should have caught this + + # handle strings + if isinstance(config, str): + return Template(config).safe_substitute(env) + + # handle other types + elif isinstance(config, dict): + return { + k: substitute_env_vars(v, env) for k, v in config.items() if v is not None + } + + # handle lists + elif isinstance(config, list): + return [substitute_env_vars(v, env) for v in config] + + return config