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

interpolation.mddocs/

Interpolation & Resolvers

Variable interpolation system with custom resolvers for dynamic value computation, including built-in resolvers and registration of custom resolver functions.

Capabilities

Interpolation Functions

Helper functions for creating interpolation expressions in configurations.

def II(interpolation: str) -> Any:
    """
    Create node interpolation equivalent to ${interpolation}.
    
    Parameters:
    - interpolation: Interpolation string (e.g., "server.host")
    
    Returns:
    Interpolation expression as "${interpolation}"
    
    Usage:
    - II("server.host") creates "${server.host}"
    - Used for referencing other config values
    """

def SI(interpolation: str) -> Any:
    """
    Create string interpolation for embedding in strings.
    
    Parameters:
    - interpolation: String with embedded interpolations
    
    Returns:
    String with interpolation patterns
    
    Usage:
    - SI("http://${server.host}:${server.port}")  
    - Used for string templates with variable substitution
    """

Resolver Management

Functions for registering and managing custom resolver functions that compute dynamic values.

def register_new_resolver(name, resolver, replace=False, use_cache=False):
    """
    Register a custom resolver function.
    
    Parameters:
    - name: Resolver name for use in interpolations
    - resolver: Function that computes resolved values
    - replace: Whether to replace existing resolver with same name
    - use_cache: Whether to cache resolver results
    
    Examples:
    - register_new_resolver("env", os.getenv)
    - register_new_resolver("now", lambda: datetime.now().isoformat())
    """

def has_resolver(name):
    """
    Check if resolver is registered.
    
    Parameters:
    - name: Resolver name to check
    
    Returns:
    True if resolver exists, False otherwise
    """

def clear_resolvers():
    """
    Clear all registered resolvers and re-register built-in defaults.
    
    Removes all custom resolvers but preserves OmegaConf's built-in
    resolvers like "oc.env", "oc.decode", etc.
    """

def clear_resolver(name):
    """
    Clear specific resolver by name.
    
    Parameters:
    - name: Name of resolver to remove
    """

Legacy Resolver Support

def register_resolver(name, resolver):
    """
    DEPRECATED: Register resolver (legacy interface).
    
    Parameters:
    - name: Resolver name
    - resolver: Resolver function
    
    Note: Use register_new_resolver() instead
    """

def legacy_register_resolver(name, resolver):
    """
    Register resolver using legacy interface.
    
    Parameters:
    - name: Resolver name  
    - resolver: Resolver function
    """

Interpolation Inspection

Methods for detecting and working with interpolation expressions.

def is_interpolation(node, key=None):
    """
    Check if node or key contains interpolation.
    
    Parameters:
    - node: Configuration node to check
    - key: Optional specific key to check
    
    Returns:
    True if value contains interpolation expressions
    """

Built-in Resolvers

OmegaConf provides several built-in resolvers for common use cases:

Environment Variable Resolver

# Access environment variables
config = OmegaConf.create({
    "database_url": "${oc.env:DATABASE_URL}",
    "debug": "${oc.env:DEBUG,false}"  # With default value
})

Decode Resolver

# Decode base64 strings
config = OmegaConf.create({
    "secret": "${oc.decode:base64,SGVsbG8gV29ybGQ=}"  # "Hello World"
})

Usage Examples

Basic Interpolation

from omegaconf import OmegaConf

config = OmegaConf.create({
    "server": {
        "host": "localhost",
        "port": 8080
    },
    "database": {
        "host": "${server.host}",  # References server.host
        "url": "postgresql://${database.host}:5432/mydb"
    },
    "api": {
        "base_url": "http://${server.host}:${server.port}",
        "endpoints": {
            "users": "${api.base_url}/users",
            "posts": "${api.base_url}/posts"
        }
    }
})

# Interpolations are resolved when accessed
print(config.database.host)  # "localhost"  
print(config.api.endpoints.users)  # "http://localhost:8080/users"

Helper Functions

from omegaconf import OmegaConf, II, SI

# Using II() for node interpolation
config = OmegaConf.create({
    "server": {"host": "localhost", "port": 8080},
    "client": {
        "server_host": II("server.host"),  # Same as "${server.host}"
        "url": SI("http://${server.host}:${server.port}/api")
    }
})

Custom Resolvers

import os
from datetime import datetime
from omegaconf import OmegaConf

# Register environment variable resolver
OmegaConf.register_new_resolver("env", lambda key, default=None: os.getenv(key, default))

# Register timestamp resolver
OmegaConf.register_new_resolver("now", lambda: datetime.now().isoformat())

# Register computation resolver
OmegaConf.register_new_resolver("add", lambda x, y: int(x) + int(y))

config = OmegaConf.create({
    "database": {
        "host": "${env:DB_HOST,localhost}",  # Environment variable with default
        "password": "${env:DB_PASSWORD}"      # Environment variable
    },
    "deployment": {
        "timestamp": "${now:}",               # Current timestamp
        "total_workers": "${add:4,8}"         # Computed value: 12
    }
})

print(config.database.host)        # Value from DB_HOST env var or "localhost"
print(config.deployment.timestamp) # Current ISO timestamp
print(config.deployment.total_workers)  # 12

Resolver with Caching

from omegaconf import OmegaConf
import random

# Expensive computation that should be cached
def expensive_computation():
    print("Computing expensive value...")
    return random.randint(1000, 9999)

# Register with caching enabled
OmegaConf.register_new_resolver("expensive", expensive_computation, use_cache=True)

config = OmegaConf.create({
    "value1": "${expensive:}",
    "value2": "${expensive:}",  # Same resolver call
    "value3": "${expensive:}"   # Same resolver call
})

# Resolver function called only once due to caching
print(config.value1)  # Prints "Computing expensive value..." and returns value
print(config.value2)  # Returns cached value (no print)
print(config.value3)  # Returns cached value (no print)

Complex Resolver Patterns

from omegaconf import OmegaConf
import json

# Register JSON parsing resolver
OmegaConf.register_new_resolver("json", lambda s: json.loads(s))

# Register file reading resolver  
OmegaConf.register_new_resolver("file", lambda path: open(path).read().strip())

# Register conditional resolver
OmegaConf.register_new_resolver("if", lambda condition, true_val, false_val: true_val if condition == "true" else false_val)

config = OmegaConf.create({
    "features": "${json:[\"auth\", \"logging\", \"metrics\"]}",  # Parse JSON array
    "version": "${file:VERSION}",                               # Read from file
    "debug_mode": "${if:${env:DEBUG,false},debug,production}"   # Conditional logic
})

print(config.features)    # ["auth", "logging", "metrics"] 
print(config.version)     # Contents of VERSION file
print(config.debug_mode)  # "debug" or "production" based on DEBUG env var

Resolver Management

from omegaconf import OmegaConf

# Check if resolver exists
if OmegaConf.has_resolver("env"):
    print("Environment resolver available")

# Clear specific resolver
OmegaConf.clear_resolver("env")

# Clear all resolvers (keeps built-ins)
OmegaConf.clear_resolvers()

# Re-register custom resolvers after clearing
OmegaConf.register_new_resolver("env", os.getenv)

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