Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import logging
from typing import Any, Optional

# We want to support environment variable replacement in the configuration
# similarly to how it is done in llama-stack, so we use their function directly
from llama_stack.core.stack import replace_env_vars

import yaml
from models.config import (
Configuration,
Expand All @@ -16,6 +20,7 @@
DatabaseConfiguration,
)


logger = logging.getLogger(__name__)


Expand All @@ -38,6 +43,7 @@ def load_configuration(self, filename: str) -> None:
"""Load configuration from YAML file."""
with open(filename, encoding="utf-8") as fin:
config_dict = yaml.safe_load(fin)
config_dict = replace_env_vars(config_dict)
logger.info("Loaded configuration: %s", config_dict)
self.init_from_dict(config_dict)

Comment on lines 43 to 49
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Stop logging full configuration (secrets leak) and harden env-var substitution handling.

Now that secrets can come from env vars, logging the entire config at info level risks leaking credentials. Also, yaml.safe_load can return None on empty files; passing that into replace_env_vars will likely error.

  • Do not log the full configuration.
  • Handle None from yaml.safe_load.
  • Add defensive error handling around replace_env_vars to fail fast with a clear message.

Apply this diff:

         with open(filename, encoding="utf-8") as fin:
-            config_dict = yaml.safe_load(fin)
-            config_dict = replace_env_vars(config_dict)
-            logger.info("Loaded configuration: %s", config_dict)
+            config_dict = yaml.safe_load(fin) or {}
+            try:
+                config_dict = replace_env_vars(config_dict)
+            except Exception as e:
+                logger.error("Failed to apply environment variable substitution: %s", e)
+                raise
+            # Avoid logging secrets; log only the top-level sections/keys.
+            logger.info("Loaded configuration sections: %s", list(config_dict.keys()))
             self.init_from_dict(config_dict)

Optional follow-ups I can help with:

  • Add unit tests covering nested env-var replacement, missing variables behavior, and type casting to ensure values still validate against Configuration. Want me to draft these?
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"""Load configuration from YAML file."""
with open(filename, encoding="utf-8") as fin:
config_dict = yaml.safe_load(fin)
config_dict = replace_env_vars(config_dict)
logger.info("Loaded configuration: %s", config_dict)
self.init_from_dict(config_dict)
"""Load configuration from YAML file."""
with open(filename, encoding="utf-8") as fin:
config_dict = yaml.safe_load(fin) or {}
try:
config_dict = replace_env_vars(config_dict)
except Exception as e:
logger.error("Failed to apply environment variable substitution: %s", e)
raise
# Avoid logging secrets; log only the top-level sections/keys.
logger.info("Loaded configuration sections: %s", list(config_dict.keys()))
self.init_from_dict(config_dict)
🤖 Prompt for AI Agents
In src/configuration.py around lines 43 to 49, stop logging the entire
configuration (to avoid leaking secrets), handle yaml.safe_load possibly
returning None, and add defensive error handling around replace_env_vars to fail
fast with a clear message; specifically, treat a None result from safe_load as
an empty dict (or raise a clear error), wrap the call to replace_env_vars in a
try/except that catches exceptions and raises/ logs a concise ValueError with
context (but do not include config contents or secret values), and replace the
info-level log of the full config with a non-sensitive message (e.g.,
"configuration loaded" or a debug log of a sanitized summary) before calling
self.init_from_dict.

Expand Down