Configuration Management
Overview
The configuration module is a robust, type-safe system that provides the foundation for all configurable components within the Athomic Layer. It is built upon two key libraries:
- Dynaconf: For layered configuration loading from multiple sources (files, environment variables, Vault, etc.).
- Pydantic: For strict, type-safe validation of the configuration structure at startup.
This combination ensures that the application starts with a valid and predictable configuration, failing fast if any required settings are missing or malformed.
Key Features
- Layered Loading: Settings are loaded from
.tomlfiles and can be individually overridden by environment variables. - Environment Switching: Easily switch between environments (e.g.,
development,production) by setting a single environment variable. - Type Safety: The entire configuration is parsed into a strongly-typed Pydantic model (
AppSettings), providing auto-completion and static analysis benefits. - Integrated Secret Management: Handles sensitive values securely, either by reading them directly or by resolving references to external secret managers like Vault at runtime.
How It Works
The configuration is loaded and validated in a two-step process during application startup:
- Loading with Dynaconf: The
DynaconfLoaderreads all specified.tomlfiles, merges them based on the current environment, and then applies any overrides from environment variables. - Validation with Pydantic: The raw dictionary loaded by Dynaconf is passed to the root
AppSettingsPydantic model. Pydantic recursively validates the entire structure, coercing types and raising aValidationErrorif any part of the configuration is invalid.
Accessing Settings
The primary way to access configuration throughout the application is via the get_settings() function. This function is cached, ensuring that the loading and validation process happens only once.
from nala.athomic.config import get_settings
settings = get_settings()
print(settings.app_name)
print(settings.database.default_document_connection)
Configuration Files & Environments
By default, the application loads configuration from settings.toml. You can create additional files for different environments, like development.toml or production.toml.
To activate a specific environment, set the NALA_ENV_FOR_DYNACONF environment variable. Dynaconf will then automatically merge the base settings.toml with the environment-specific file.
export NALA_ENV_FOR_DYNACONF=production
# The application will now load settings from settings.toml and merge them with production.toml
Environment Variables Override
Any setting can be overridden using environment variables. This is particularly useful for containerized deployments (e.g., Docker, Kubernetes).
- Prefix: All variables must start with
NALA_. - Separator: Nested keys are separated by a double underscore
__.
For example, to override the database name for the default MongoDB connection, you would set the following environment variable:
export NALA_DATABASE__DOCUMENTS__DEFAULT_MONGO__PROVIDER__DATABASE_NAME="my_production_db"
Secret Management
The configuration system has first-class support for handling secrets securely.
1. Direct Value (from Environment)
For secrets provided directly as environment variables, you can use Pydantic's SecretStr type in the configuration model. This ensures the value is automatically masked when logged or printed.
2. Secret Reference (from Vault, etc.)
For a more secure approach, you can configure a reference to a secret stored in an external manager. This is done using the SecretValue model, which requires a path and a key.
# In your settings.toml
[default.database.documents.default_mongo.provider]
# This does not contain the actual password.
# It's a reference to a secret stored in Vault at path 'database/mongo' with key 'password'.
password = { path = "database/mongo", key = "password" } # pragma: allowlist secret
At startup, the SecretsManager traverses the entire configuration and replaces these SecretValue objects with a lazy-loading proxy. The actual secret is only fetched from the provider (e.g., Vault) at the moment it is first needed.
API Reference
nala.athomic.config.get_settings()
cached
Loads, validates, and returns the application settings as a singleton.
This is the primary entry point for accessing application configuration. It
uses @lru_cache to ensure that the potentially expensive process of loading
and validating settings from files and environment variables happens only once.
Returns:
| Name | Type | Description |
|---|---|---|
AppSettings |
AppSettings
|
A validated Pydantic model containing the entire |
AppSettings
|
application configuration. |
nala.athomic.config.schemas.app_settings.AppSettings
Bases: BaseModel
The root Pydantic model for the entire application's configuration.
nala.athomic.config.schemas.models.SecretValue
Bases: BaseModel
Represents a structured reference to a secret in an external provider.
Instead of hardcoding secrets in configuration, this model is used to point
to a secret's location (e.g., in HashiCorp Vault). The SecretsManager
resolves these references at runtime to fetch the actual secret value.
Attributes:
| Name | Type | Description |
|---|---|---|
path |
str
|
The path or mount point in the secrets backend where the group of secrets is stored (e.g., 'database/production'). |
key |
str
|
The specific key within the given path that holds the secret value (e.g., 'password'). |