Spaces:
Running
Running
File size: 2,015 Bytes
0017280 b1b0945 0017280 106354e 9815e49 0017280 f95cdb7 9093d8f fbd18c8 9093d8f 0017280 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | """Loads config.yaml and .env, exposes settings as a dict."""
import os
from pathlib import Path
import yaml
from dotenv import load_dotenv
_ENV_KEY_MAP = {
"openai": "OPENAI_API_KEY",
"anthropic": "ANTHROPIC_API_KEY",
"gemini": "GEMINI_API_KEY",
"hugging-face": "HF_API_KEY",
}
def load_config(config_path: str = None) -> dict:
if config_path is None:
config_path = Path(__file__).resolve().parent.parent / "config.yaml"
env_path = Path(config_path).resolve().parent / ".env"
if env_path.exists():
load_dotenv(str(env_path))
if not Path(config_path).exists():
raise FileNotFoundError(
f"Config file not found: {config_path}\n"
"Run 'python setup.py' first to generate config.yaml and .env."
)
with open(config_path, "r", encoding="utf-8") as f:
cfg = yaml.safe_load(f) or {}
if not isinstance(cfg, dict):
raise ValueError(
f"Config file must contain a YAML mapping (dict), got {type(cfg).__name__}. "
"Run 'python setup.py' to regenerate config.yaml."
)
# Normalize None-valued sections to empty dicts so chained .get() never
# fails with AttributeError (e.g. `llm:` with no sub-keys → None).
# Recurse into nested dicts so `paths:\n vector_db:` also gets normalized.
def _normalize_nulls(d):
for key in list(d.keys()):
if d[key] is None:
d[key] = {}
elif isinstance(d[key], dict):
_normalize_nulls(d[key])
_normalize_nulls(cfg)
for provider, env_var in _ENV_KEY_MAP.items():
env_val = os.environ.get(env_var)
if env_val:
cfg.setdefault("api_keys", {})[provider] = env_val
return cfg
def get_api_key(cfg: dict, provider: str) -> str:
env_var = _ENV_KEY_MAP.get(provider)
if env_var:
env_val = os.environ.get(env_var)
if env_val:
return env_val
return cfg.get("api_keys", {}).get(provider, "")
|