mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-04-03 09:52:33 +00:00
feat(config): add {env:VAR} syntax for environment variable references
Add secret_resolver module to resolve {env:VAR_NAME} placeholders in
config files. Allows storing sensitive values like API keys in
environment variables instead of config.json.
This commit is contained in:
parent
214bf66a29
commit
beaa8de2c5
@ -4,6 +4,7 @@ import json
|
||||
from pathlib import Path
|
||||
|
||||
from nanobot.config.schema import Config
|
||||
from nanobot.config.secret_resolver import resolve_config
|
||||
|
||||
|
||||
# Global variable to store current config path (for multi-instance support)
|
||||
@ -40,6 +41,7 @@ def load_config(config_path: Path | None = None) -> Config:
|
||||
with open(path, encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
data = _migrate_config(data)
|
||||
data = resolve_config(data) # Resolve {env:VAR} references
|
||||
return Config.model_validate(data)
|
||||
except (json.JSONDecodeError, ValueError) as e:
|
||||
print(f"Warning: Failed to load config from {path}: {e}")
|
||||
|
||||
48
nanobot/config/secret_resolver.py
Normal file
48
nanobot/config/secret_resolver.py
Normal file
@ -0,0 +1,48 @@
|
||||
"""Secret reference resolver for configuration.
|
||||
|
||||
Supports {env:VARIABLE_NAME} syntax to reference environment variables.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
# Pattern matches {env:VAR_NAME} where VAR_NAME follows env var naming conventions
|
||||
_REF_PATTERN = re.compile(r"\{env:([A-Z_][A-Z0-9_]*)\}")
|
||||
|
||||
|
||||
def resolve_env_vars(value: str) -> str:
|
||||
"""Resolve {env:VAR} references in a string.
|
||||
|
||||
Args:
|
||||
value: String that may contain {env:VAR} references.
|
||||
|
||||
Returns:
|
||||
String with all {env:VAR} references replaced by their values.
|
||||
Unresolved references are left unchanged.
|
||||
"""
|
||||
def replacer(match: re.Match[str]) -> str:
|
||||
var_name = match.group(1)
|
||||
env_value = os.environ.get(var_name)
|
||||
if env_value is None:
|
||||
return match.group(0) # Keep original if env var doesn't exist
|
||||
return env_value
|
||||
|
||||
return _REF_PATTERN.sub(replacer, value)
|
||||
|
||||
|
||||
def resolve_config(obj):
|
||||
"""Recursively resolve {env:VAR} references in a configuration object.
|
||||
|
||||
Args:
|
||||
obj: Configuration value (str, dict, list, or other).
|
||||
|
||||
Returns:
|
||||
Configuration with all {env:VAR} references resolved.
|
||||
"""
|
||||
if isinstance(obj, str):
|
||||
return resolve_env_vars(obj)
|
||||
if isinstance(obj, dict):
|
||||
return {k: resolve_config(v) for k, v in obj.items()}
|
||||
if isinstance(obj, list):
|
||||
return [resolve_config(item) for item in obj]
|
||||
return obj
|
||||
Loading…
x
Reference in New Issue
Block a user