envyaml
Mastering envyaml: A Practical Playbook for YAML Configs with Environment Variables
Key Takeaways
- envyaml is a lightweight Python library that loads YAML configuration files and seamlessly substitutes environment variables.
- Installation is a single
pip install envyamlcommand. - Use
envyaml.loadto read a file, then reference values like a normal dictionary. - envyaml supports nested interpolation, default values, and custom loaders.
- It outperforms
python-dotenvfor YAML files, and is simpler thanpydanticfor configuration parsing. - Follow the checklist below to avoid common pitfalls and ensure secure, maintainable configs.
Why envyaml?
Modern Python applications often require flexible configuration that can change between environments (dev, staging, prod). YAML files provide readability, while environment variables keep secrets out of source control. envyaml bridges the two, allowing you to:
- Write a single YAML file for all environments.
- Inject environment-specific values without duplication.
- Keep secrets in
.envfiles or container secrets.
Installation & Setup
Step 1: Install the Package
pip install envyaml
Step 2: Create a YAML Config
# config.yaml
database:
host: ${DB_HOST}
port: ${DB_PORT:5432}
user: ${DB_USER}
password: ${DB_PASSWORD}
logging:
level: ${LOG_LEVEL:INFO}
file: /var/log/app.log
Step 3: Load the Config in Your Code
from envyaml import load
config = load("config.yaml")
print(config["database"]["host"])
Advanced Features
Custom Default Values
Use ${VAR:default} syntax to provide a fallback when an environment variable is missing.
Nested Interpolation
envyaml automatically resolves nested variables, e.g., ${BASE_URL}/api where BASE_URL is defined elsewhere.
Custom Loaders
For complex scenarios, you can pass a custom loader to load:
from envyaml import load
from yaml import SafeLoader
config = load("config.yaml", loader=SafeLoader)
Best Practices Checklist
- â
Keep secrets in environment variables, never in
config.yaml. - â Use default values for non-sensitive settings.
- â
Validate configuration at startup (e.g., using
pydanticor custom checks). - â
Store a
config.example.yamlin the repo to document required variables. - â
Use
dotenvor Docker secrets to inject variables into the runtime environment. - â Avoid hardcoding file paths; use relative paths or environment variables.
- â Log the loaded configuration (masking secrets) to aid debugging.
Comparison with Other Config Libraries
| Feature | envyaml | python-dotenv | pydantic |
|---|---|---|---|
| File Format | YAML | dotenv (.env) | JSON / Pydantic models (YAML via pyyaml) |
| Environment Variable Interpolation | âď¸ Built-in | âď¸ Built-in | âď¸ via custom validators |
| Nested Configs | âď¸ | âď¸ | âď¸ (via models) |
| Validation | âď¸ (manual) | âď¸ | âď¸ (built-in) |
| Installation Size | ~10âŻKB | ~5âŻKB | ~200âŻKB |
| Use Case | Lightweight YAML configs with env vars | Simple .env files | Complex typed schemas |
FAQs
1. How do I secure my secrets when using envyaml?
Never store secrets directly in the YAML file. Use environment variables, dotenv files (excluded from version control), or container secrets. envyaml will replace placeholders with the values from the environment at runtime.
2. Can I use envyaml with Docker Compose?
Yes. Define the environment variables in the docker-compose.yml or in a .env file. When the container starts, envyaml will resolve the placeholders automatically.
3. Does envyaml support validation of config values?
Not directly. For validation, combine envyaml with pydantic or a custom validation function. Load the YAML with envyaml, then pass the resulting dictionary to a pydantic model for type checking and validation.