fancy-config
A flexible, type-safe, and hierarchical configuration management system for Python.
🌟 Features
- Type-safe configuration: Define configuration options with specific types, automatic type conversion
- Validation: Options can be marked as required, nullable, with default values
- Hierarchical structure: Support for nested configuration objects
- Multiple data sources: Load configuration from YAML files, dictionaries, or command-line arguments
- Extensible: Create custom configuration loaders for any data source
- Advanced features: Lazy evaluation, placeholder values, configuration lists
📦 Installation
pip install fancy-config
🚀 Quick Start
from fancy import config as cfg
# Define a configuration class
class MyConfig(cfg.BaseConfig):
# Required integer option
name = cfg.Option(type=str, required=True)
# Integer option with a default value
count = cfg.Option(type=int, default=10)
# Option that can be null
description = cfg.Option(type=str, nullable=True)
# Computed property (lazy evaluation)
name_length = cfg.Lazy[int](lambda self: len(self.name))
# Create a configuration from a dictionary
config = MyConfig({
"name": "Example Config",
"description": "This is an example configuration"
})
# Access configuration values
print(config.name) # "Example Config"
print(config.count) # 10 (default value)
print(config.name_length) # 14 (computed)
# Convert to dictionary
config_dict = config.to_dict()
📋 Hierarchical Configuration
from fancy import config as cfg
# Define a sub-configuration
class DatabaseConfig(cfg.BaseConfig):
host = cfg.Option(type=str, default="localhost")
port = cfg.Option(type=int, default=5432)
username = cfg.Option(type=str, required=True)
password = cfg.Option(type=str, required=True)
# Define a main configuration that includes the sub-configuration
class AppConfig(cfg.BaseConfig):
app_name = cfg.Option(type=str, required=True)
debug = cfg.Option(type=bool, default=False)
database = cfg.Option(type=DatabaseConfig, default={})
# Create a configuration with nested values
config = AppConfig({
"app_name": "My Application",
"debug": True,
"database": {
"username": "admin",
"password": "secret"
}
})
# Access nested configuration
print(config.app_name) # "My Application"
print(config.database.host) # "localhost" (default value)
print(config.database.username) # "admin"
📝 Loading from YAML Files
from fancy import config as cfg
from pathlib import Path
class MyConfig(cfg.BaseConfig):
name = cfg.Option(type=str)
count = cfg.Option(type=int)
# Load from a YAML file
yaml_loader = cfg.YamlConfigLoader(Path("config.yaml"))
config = MyConfig(loader=yaml_loader)
Example YAML file:
name: Example Config
count: 42
📋 List Configuration
from fancy import config as cfg
class ServerConfig(cfg.BaseConfig):
host = cfg.Option(type=str, required=True)
port = cfg.Option(type=int, default=80)
class ClusterConfig(cfg.BaseConfig):
servers = cfg.Option(type=[ServerConfig]) # List of ServerConfig objects
# Create a configuration with a list of servers
config = ClusterConfig({
"servers": [
{"host": "server1.example.com", "port": 8080},
{"host": "server2.example.com"}
]
})
# Access list elements
print(config.servers[0].host) # "server1.example.com"
print(config.servers[1].port) # 80 (default value)
🧪 Advanced Features
Boolean Processing
from fancy import config as cfg
class FeatureConfig(cfg.BaseConfig):
# Automatically converts various string representations to boolean
enabled = cfg.Option(type=bool)
config = FeatureConfig({
"enabled": "yes" # Will be converted to True
})
# Other valid string values for boolean:
# "true", "on", "1" -> True
# "false", "off", "0", "no" -> False
Custom Type Conversion
from fancy import config as cfg
from pathlib import Path
def path_converter(value):
return Path(value)
class FileConfig(cfg.BaseConfig):
location = cfg.Option(type=path_converter)
config = FileConfig({"location": "/tmp/file.txt"})
print(type(config.location)) # <class 'pathlib.Path'>
Special Case: Custom Type Conversion with Static Methods
Starting with Python 3.10, staticmethod objects are callable, allowing you to define custom type converters directly within the configuration class. This approach is useful when the custom converter is specific to the configuration and does not need to be reused elsewhere.
from fancy import config as cfg
from pathlib import Path
class FileConfig(cfg.BaseConfig):
@staticmethod
def path_converter(value):
return Path(value)
location = cfg.Option(type=path_converter)
config = FileConfig({"location": "/tmp/file.txt"})
print(type(config.location)) # <class 'pathlib.Path'>
This method keeps the custom converter encapsulated within the configuration class, improving code organization and readability.
Lazy Computed Values
from fancy import config as cfg
class ReportConfig(cfg.BaseConfig):
width = cfg.Option(type=int, default=100)
height = cfg.Option(type=int, default=50)
# Computed only when accessed
area = cfg.Lazy[int](lambda self: self.width * self.height)
# Can depend on other computed values
description = cfg.Lazy[str](lambda self: f"Report size: {self.area} square units")
config = ReportConfig()
print(config.area) # 5000 (100 * 50)
print(config.description) # "Report size: 5000 square units"
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
Metadata
Release files for fancy-config 0.13.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fancy_config-0.13.5-py3-none-any.whl | Python 3 | none | any | Details |
Release files / fancy_config-0.13.5-py3-none-any.whl
| Download URL | fancy_config-0.13.5-py3-none-any.whl |
|---|---|
| Size | 35.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e82ef7263f51462c8082ce7f9ff1571bcfb5d79679807a02033627156fb007c6
|
|
BLAKE2b-256 checksum How to use checksums |
8e20f2c0e26c66f959ce4ea94c45973e21257e77493c61ea88790d57ddf5cdd2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|