CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-omegaconf

A flexible configuration library that provides hierarchical configuration management with YAML support, variable interpolation, and type validation

Pending
Overview
Eval results
Files

structured-configs.mddocs/

Structured Configs

Integration with Python dataclasses and attrs classes for type-safe configuration schemas, enabling automatic validation and IDE support.

Capabilities

Structured Config Creation

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
    """

Object Instantiation

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
    """

Type Information

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
    """

Dataclass Integration

Basic Dataclass Usage

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"]
))

Type Validation

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")

Optional and Union Types

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            # ✓

Nested Structured Configs

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 = 60

Attrs Integration

import 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"

Object Conversion

Converting Back to Objects

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)

Recursive Object Conversion

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"

Advanced Patterns

Inheritance with Structured Configs

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)

Factory Functions and Complex Defaults

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"

Struct Mode with Structured Configs

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

docs

configuration-creation.md

containers.md

index.md

interpolation.md

manipulation.md

structured-configs.md

types-and-nodes.md

utilities.md

tile.json