A flexible configuration library that provides hierarchical configuration management with YAML support, variable interpolation, and type validation
—
Integration with Python dataclasses and attrs classes for type-safe configuration schemas, enabling automatic validation and IDE support.
Creates type-safe configurations from Python dataclasses and attrs classes with automatic validation.
def structured(obj, parent=None, flags=None):
"""
Create config from structured object (dataclass/attrs).
Parameters:
- obj: Dataclass/attrs class or instance
- parent: Parent node for nested configs
- flags: Configuration flags
Returns:
DictConfig with type validation based on structured schema
Features:
- Automatic type validation based on annotations
- Support for default values and factory functions
- Integration with typing module (Optional, Union, etc.)
- Preservation of class structure and relationships
"""Converts configurations back to Python objects with proper type instantiation.
def to_object(cfg):
"""
Convert configuration to instantiated objects.
Parameters:
- cfg: Configuration to convert (must be from structured config)
Returns:
Instantiated dataclass/attrs object with validated values
Notes:
- Only works with configs created from structured objects
- Recursively instantiates nested structured configs
- Validates all values against original type annotations
"""Methods for inspecting type information in structured configurations.
def get_type(obj, key=None):
"""
Get type information for structured config.
Parameters:
- obj: Structured configuration object
- key: Optional specific key to inspect
Returns:
Type information from original dataclass/attrs annotations
"""from dataclasses import dataclass, field
from typing import List, Optional
from omegaconf import OmegaConf
@dataclass
class DatabaseConfig:
host: str = "localhost"
port: int = 5432
username: str = "admin"
password: Optional[str] = None
pool_size: int = 10
@dataclass
class AppConfig:
database: DatabaseConfig = field(default_factory=DatabaseConfig)
debug: bool = False
features: List[str] = field(default_factory=list)
# Create from class (uses defaults)
config = OmegaConf.structured(AppConfig)
print(config.database.host) # "localhost"
print(config.debug) # False
# Create from instance (with overrides)
config = OmegaConf.structured(AppConfig(
database=DatabaseConfig(host="remote-db", port=3306),
debug=True,
features=["auth", "logging"]
))from dataclasses import dataclass
from omegaconf import OmegaConf, ValidationError
@dataclass
class Config:
name: str
count: int
rate: float
enabled: bool
config = OmegaConf.structured(Config)
# Type conversion works
config.name = "test" # str -> str ✓
config.count = "42" # str -> int ✓
config.rate = "3.14" # str -> float ✓
config.enabled = "true" # str -> bool ✓
# Type validation prevents errors
try:
config.count = "invalid" # Cannot convert to int
except ValidationError:
print("Validation failed")
try:
config.new_field = "value" # New fields not allowed in struct mode
except Exception:
print("Cannot add new fields")from dataclasses import dataclass
from typing import Optional, Union
from omegaconf import OmegaConf
@dataclass
class Config:
required_field: str
optional_field: Optional[str] = None
union_field: Union[str, int] = "default"
optional_union: Optional[Union[str, int]] = None
config = OmegaConf.structured(Config)
# Optional fields can be None
config.optional_field = None # ✓
config.optional_field = "some value" # ✓
# Union fields accept multiple types
config.union_field = "string value" # ✓
config.union_field = 42 # ✓
# Optional union combines both behaviors
config.optional_union = None # ✓
config.optional_union = "string" # ✓
config.optional_union = 123 # ✓from dataclasses import dataclass, field
from typing import List
from omegaconf import OmegaConf
@dataclass
class ServerConfig:
host: str = "localhost"
port: int = 8080
ssl_enabled: bool = False
@dataclass
class DatabaseConfig:
url: str = "sqlite:///app.db"
pool_size: int = 5
timeout: int = 30
@dataclass
class AppConfig:
name: str = "MyApp"
servers: List[ServerConfig] = field(default_factory=list)
database: DatabaseConfig = field(default_factory=DatabaseConfig)
# Create nested structured config
config = OmegaConf.structured(AppConfig(
servers=[
ServerConfig(host="web1", port=80),
ServerConfig(host="web2", port=80, ssl_enabled=True)
]
))
# Access nested values with type safety
print(config.servers[0].host) # "web1"
print(config.servers[1].ssl_enabled) # True
print(config.database.pool_size) # 5
# Modify nested structures
config.servers[0].port = 8080
config.database.timeout = 60import attr
from typing import Optional
from omegaconf import OmegaConf
@attr.s
class DatabaseConfig:
host: str = attr.ib(default="localhost")
port: int = attr.ib(default=5432)
ssl: bool = attr.ib(default=False)
@attr.s
class AppConfig:
name: str = attr.ib()
database: DatabaseConfig = attr.ib(factory=DatabaseConfig)
debug: Optional[bool] = attr.ib(default=None)
# Works same as dataclasses
config = OmegaConf.structured(AppConfig(name="MyApp"))
print(config.database.host) # "localhost"from dataclasses import dataclass
from omegaconf import OmegaConf
@dataclass
class Config:
name: str = "default"
value: int = 42
# Create and modify config
config = OmegaConf.structured(Config)
config.name = "modified"
config.value = 100
# Convert back to dataclass instance
obj = OmegaConf.to_object(config)
print(type(obj)) # <class '__main__.Config'>
print(obj.name) # "modified"
print(obj.value) # 100
# Original dataclass methods work
print(obj) # Config(name='modified', value=100)from dataclasses import dataclass, field
from typing import List
from omegaconf import OmegaConf
@dataclass
class Item:
name: str
quantity: int
@dataclass
class Order:
id: str
items: List[Item] = field(default_factory=list)
# Create structured config
config = OmegaConf.structured(Order(
id="order-123",
items=[Item("apple", 5), Item("banana", 3)]
))
# Convert entire structure back to objects
order = OmegaConf.to_object(config)
print(type(order)) # <class '__main__.Order'>
print(type(order.items[0])) # <class '__main__.Item'>
print(order.items[0].name) # "apple"from dataclasses import dataclass
from omegaconf import OmegaConf
@dataclass
class BaseConfig:
name: str = "base"
version: str = "1.0"
@dataclass
class ServerConfig(BaseConfig):
host: str = "localhost"
port: int = 8080
@dataclass
class DatabaseConfig(BaseConfig):
url: str = "sqlite:///db.sqlite"
pool_size: int = 5
# Inheritance works naturally
server_config = OmegaConf.structured(ServerConfig)
print(server_config.name) # "base" (inherited)
print(server_config.host) # "localhost" (own field)from dataclasses import dataclass, field
from datetime import datetime
from typing import Dict, Any
from omegaconf import OmegaConf
def get_timestamp():
return datetime.now().isoformat()
@dataclass
class Config:
id: str = field(default_factory=lambda: f"config-{get_timestamp()}")
metadata: Dict[str, Any] = field(default_factory=dict)
created_at: str = field(default_factory=get_timestamp)
config = OmegaConf.structured(Config)
print(config.id) # "config-2023-10-15T14:30:00.123456"
print(config.created_at) # "2023-10-15T14:30:00.123456"from dataclasses import dataclass
from omegaconf import OmegaConf
@dataclass
class StrictConfig:
allowed_field: str = "value"
# Structured configs are automatically in struct mode
config = OmegaConf.structured(StrictConfig)
try:
config.new_field = "not allowed" # Raises exception
except Exception:
print("Cannot add fields to structured config")
# Use open_dict to temporarily allow new fields
with OmegaConf.open_dict(config):
config.temporary_field = "allowed"
print(config.temporary_field) # "allowed"Install with Tessl CLI
npx tessl i tessl/pypi-omegaconf