A Python library for managing hierarchical configuration files with profile-based inheritance and variable interpolation
Project description
Profile Config
Hierarchical profile-based configuration management for Python applications.
Profile Config provides a robust solution for managing application configuration across different environments and deployment scenarios. It supports hierarchical configuration file discovery, profile inheritance, variable interpolation, and runtime overrides.
Features
- Hierarchical Discovery: Automatically discovers configuration files by walking up the directory tree
- Profile Inheritance: Profiles can inherit from other profiles with circular dependency detection
- Multiple Formats: Supports YAML, JSON, and TOML configuration files
- Variable Interpolation: Supports variable substitution using
${variable}syntax - Runtime Overrides: Apply configuration overrides at runtime
- Configurable Search: Customize search patterns and file locations
- Type Safety: Built on OmegaConf for robust configuration merging
Installation
pip install profile-config
For TOML support on Python < 3.11:
pip install profile-config[toml]
Quick Start
Create a configuration file at myapp/config.yaml:
defaults:
database_host: localhost
database_port: 5432
debug: false
profiles:
development:
debug: true
database_name: myapp_dev
production:
database_name: myapp_prod
database_host: prod-db.example.com
Or use TOML format at myapp/config.toml:
[defaults]
database_host = "localhost"
database_port = 5432
debug = false
[profiles.development]
debug = true
database_name = "myapp_dev"
[profiles.production]
database_name = "myapp_prod"
database_host = "prod-db.example.com"
Use in your application:
from profile_config import ProfileConfigResolver
# Resolve development profile
resolver = ProfileConfigResolver("myapp", profile="development")
config = resolver.resolve()
print(config["debug"]) # True
print(config["database_host"]) # localhost
print(config["database_name"]) # myapp_dev
Configuration File Discovery
Profile Config uses a hierarchical search strategy to discover configuration files:
-
Current Directory Tree: Walks up from current working directory
./myapp/config.{yaml,yml,json,toml}../myapp/config.{yaml,yml,json,toml}../../myapp/config.{yaml,yml,json,toml}- etc.
-
Home Directory: Searches user's home directory
$HOME/myapp/config.{yaml,yml,json,toml}
Files found in more specific locations (closer to current directory) take precedence over more general ones.
Supported Configuration Formats
YAML Format
defaults:
database_host: localhost
features:
- user_auth
- api_v2
profiles:
development:
debug: true
JSON Format
{
"defaults": {
"database_host": "localhost",
"features": ["user_auth", "api_v2"]
},
"profiles": {
"development": {
"debug": true
}
}
}
TOML Format
[defaults]
database_host = "localhost"
features = ["user_auth", "api_v2"]
[profiles.development]
debug = true
TOML Benefits:
- Type Safety: Native support for strings, integers, floats, booleans, dates
- Readable: Clean syntax without excessive nesting
- Standardized: Official specification with compliant parsers
- Rich Data Types: Arrays, inline tables, array of tables
Profile Inheritance
Profiles support inheritance using the inherits key:
profiles:
base:
database_host: localhost
timeout: 30
development:
inherits: base
debug: true
database_name: myapp_dev
staging:
inherits: development
debug: false
database_host: staging-db.example.com
TOML equivalent:
[profiles.base]
database_host = "localhost"
timeout = 30
[profiles.development]
inherits = "base"
debug = true
database_name = "myapp_dev"
[profiles.staging]
inherits = "development"
debug = false
database_host = "staging-db.example.com"
Inheritance chains are resolved automatically with circular dependency detection.
Team and Environment Management
Handle team differences and multiple environments using profiles:
profiles:
# Base environment profiles
development:
debug: true
database_name: myapp_dev
production:
debug: false
database_name: myapp_prod
# Team-specific profiles
development-team1:
inherits: development
team_id: team1
custom_endpoint: "https://team1.internal.com"
development-team2:
inherits: development
team_id: team2
custom_endpoint: "https://team2.internal.com"
production-team1:
inherits: production
team_id: team1
workers: 4
production-team2:
inherits: production
team_id: team2
workers: 8
Usage with environment variables:
import os
from profile_config import ProfileConfigResolver
# Teams set TEAM_NAME in their environment
team = os.environ.get("TEAM_NAME", "")
env = os.environ.get("ENV", "development")
profile = f"{env}-{team}" if team else env
resolver = ProfileConfigResolver("myapp", profile=profile)
config = resolver.resolve()
Variable Interpolation
Configuration values support variable interpolation:
defaults:
app_name: myapp
base_path: /opt/${app_name}
data_path: ${base_path}/data
log_path: ${base_path}/logs
profiles:
development:
base_path: /tmp/${app_name}
TOML equivalent:
[defaults]
app_name = "myapp"
base_path = "/opt/${app_name}"
data_path = "${base_path}/data"
log_path = "${base_path}/logs"
[profiles.development]
base_path = "/tmp/${app_name}"
Variables are resolved after profile inheritance is complete.
Runtime Overrides
Apply configuration overrides at runtime:
overrides = {
"database_host": "override-db.example.com",
"debug": True,
"new_setting": "runtime_value"
}
resolver = ProfileConfigResolver(
"myapp",
profile="production",
overrides=overrides
)
config = resolver.resolve()
Advanced Usage
Custom Search Configuration
resolver = ProfileConfigResolver(
config_name="myapp",
profile="development",
extensions=["yaml", "json"], # Only search these formats
search_home=False, # Don't search home directory
)
Custom Inheritance Key
# Use 'extends' instead of 'inherits'
resolver = ProfileConfigResolver(
"myapp",
profile="development",
inherit_key="extends"
)
Disable Variable Interpolation
resolver = ProfileConfigResolver(
"myapp",
profile="development",
enable_interpolation=False
)
List Available Profiles
resolver = ProfileConfigResolver("myapp")
profiles = resolver.list_profiles()
print(f"Available profiles: {profiles}")
Get Discovered Files
resolver = ProfileConfigResolver("myapp")
files = resolver.get_config_files()
for file_path in files:
print(f"Found config: {file_path}")
Configuration File Format
Configuration files support the following structure:
# Optional: specify default profile name
default_profile: development
# Optional: global defaults applied to all profiles
defaults:
timeout: 30
retries: 3
# Profile definitions
profiles:
base:
database_host: localhost
cache_enabled: true
development:
inherits: base # Optional: inherit from another profile
debug: true
database_name: myapp_dev
production:
inherits: base
database_host: prod-db.example.com
database_name: myapp_prod
cache_ttl: 3600
Format Comparison
| Feature | YAML | JSON | TOML |
|---|---|---|---|
| Readability | ✅ Excellent | ⚠️ Good | ✅ Excellent |
| Comments | ✅ Yes | ❌ No | ✅ Yes |
| Multi-line strings | ✅ Yes | ⚠️ Escaped | ✅ Yes |
| Type safety | ⚠️ Inferred | ⚠️ Limited | ✅ Native |
| Nesting | ✅ Natural | ✅ Natural | ⚠️ Verbose |
| Arrays | ✅ Clean | ✅ Standard | ✅ Clean |
| Ecosystem | ✅ Mature | ✅ Universal | ⚠️ Growing |
Recommendations:
- YAML: Best for complex nested configurations
- JSON: Best for API integration and data exchange
- TOML: Best for application configuration with type safety
Error Handling
Profile Config provides specific exceptions for different error conditions:
from profile_config import ProfileConfigResolver
from profile_config.exceptions import (
ConfigNotFoundError,
ProfileNotFoundError,
CircularInheritanceError,
ConfigFormatError
)
try:
resolver = ProfileConfigResolver("myapp", profile="nonexistent")
config = resolver.resolve()
except ConfigNotFoundError:
print("No configuration files found")
except ProfileNotFoundError as e:
print(f"Profile not found: {e}")
except CircularInheritanceError as e:
print(f"Circular inheritance detected: {e}")
except ConfigFormatError as e:
print(f"Configuration format error: {e}")
Examples
The examples/ directory contains comprehensive examples:
basic_usage.py: Basic configuration resolution and profile usageadvanced_profiles.py: Complex inheritance patterns and error handlingweb_app_config.py: Real-world web application configuration managementtoml_usage.py: TOML format features and syntax examples
Run examples:
cd examples
python basic_usage.py
python advanced_profiles.py
python web_app_config.py
python toml_usage.py
Development
Setup Development Environment
git clone https://github.com/bassmanitram/profile-config.git
cd profile-config
pip install -e ".[dev,toml]"
Run Tests
pytest
Run Tests with Coverage
pytest --cov=profile_config --cov-report=html
Code Formatting
black profile_config/ examples/
isort profile_config/ examples/
Type Checking
mypy profile_config/
License
MIT License. See LICENSE file for details.
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines and submit pull requests to the main repository.
Links
- GitHub Repository: https://github.com/bassmanitram/profile-config
- PyPI Package: https://pypi.org/project/profile-config/
- Documentation: https://bassmanitram.github.io/profile-config/
- Issue Tracker: https://github.com/bassmanitram/profile-config/issues
Changelog
See CHANGELOG.md for version history and changes.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file profile_config-1.0.1.tar.gz.
File metadata
- Download URL: profile_config-1.0.1.tar.gz
- Upload date:
- Size: 19.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b04012c52193ee724109f443da9c7c80f0a37de667a232eb275c6d8a5e97adfa
|
|
| MD5 |
0f37d51602787f4581813a9ba1af440e
|
|
| BLAKE2b-256 |
e29a96b83096a756c1cef06d64be1c66ca89879074530f00c68568fa3d108b93
|
Provenance
The following attestation bundles were made for profile_config-1.0.1.tar.gz:
Publisher:
release.yml on bassmanitram/profile-config
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
profile_config-1.0.1.tar.gz -
Subject digest:
b04012c52193ee724109f443da9c7c80f0a37de667a232eb275c6d8a5e97adfa - Sigstore transparency entry: 644681986
- Sigstore integration time:
-
Permalink:
bassmanitram/profile-config@a0fa69118392ebdc62ca5600dd581929a4cfa069 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/bassmanitram
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a0fa69118392ebdc62ca5600dd581929a4cfa069 -
Trigger Event:
push
-
Statement type:
File details
Details for the file profile_config-1.0.1-py3-none-any.whl.
File metadata
- Download URL: profile_config-1.0.1-py3-none-any.whl
- Upload date:
- Size: 20.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ef49e57a37e1e4500fc7bb29a47aca357ff4e10bcac14b8865bcc7f0cf3c2bc
|
|
| MD5 |
c5d7caec128491abfe6b47ad69b206e8
|
|
| BLAKE2b-256 |
f81ac0a6608e627ecfa9de4fcf9aae23dceae5994acee1063ec668161e652fbf
|
Provenance
The following attestation bundles were made for profile_config-1.0.1-py3-none-any.whl:
Publisher:
release.yml on bassmanitram/profile-config
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
profile_config-1.0.1-py3-none-any.whl -
Subject digest:
9ef49e57a37e1e4500fc7bb29a47aca357ff4e10bcac14b8865bcc7f0cf3c2bc - Sigstore transparency entry: 644682010
- Sigstore integration time:
-
Permalink:
bassmanitram/profile-config@a0fa69118392ebdc62ca5600dd581929a4cfa069 -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/bassmanitram
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a0fa69118392ebdc62ca5600dd581929a4cfa069 -
Trigger Event:
push
-
Statement type: