Skip to content

API Reference

Type Aliases

  • StrOrPath: str | os.PathLike[str] - All path parameters accept strings directly, Path objects, or any os.PathLike implementation. Import with from rconfig import StrOrPath for type annotations in your own code.

Common API

Core functions for everyday use. These are the primary interfaces most users will interact with.

rc.register(name, target)

Register a target class under a unique name for use in config files.

Parameters:

Parameter Type Default Description
name str required Unique identifier for the target class. This is the value used in _target_ fields.
target type required The Python class to register.

Returns: None

Raises:

Exception Condition
ValueError If name is already registered

Examples:

rc.register(name="model", target=ModelConfig)
rc.register(name="my_dataset", target=MyDataset)

rc.unregister(name)

Remove a previously registered configuration reference.

Parameters:

Parameter Type Default Description
name str required Identifier of the reference to unregister.

Returns: None

Raises:

Exception Condition
KeyError If no reference with that name exists

Examples:

rc.unregister(name="model")

rc.validate(path, *, inner_path=None, overrides=None, cli_overrides=True)

Validate a config file without instantiating (dry-run). Checks all _required_ values have been satisfied.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to the configuration file. Accepts str, Path, or any os.PathLike.
inner_path str \| None None Dot-notation path to validate only a section (e.g., "model" or "trainer.callbacks[0]"). _required_ markers outside this section are ignored. When specified, the root-level _target_ is optional and types can be inferred from parent's type hints (including list[X], set[X], dict[str, X], Sequence[X], Mapping[K, V], tuple[A, B, C], Optional[container], Annotated[X, ...], NewType, and Union[A, B] via structural matching).
overrides dict[str, Any] \| None None Dictionary of config overrides using dot notation keys.
cli_overrides bool True Whether to parse CLI overrides from sys.argv.

Returns: ValidationResult with fields:

  • valid (bool): True if validation passed with no errors
  • errors (list[ValidationError]): List of validation errors found

Raises:

Exception Condition
ConfigFileError If file cannot be loaded or parsed
InvalidInnerPathError If inner_path doesn't exist or points to a scalar

Examples:

result = rc.validate(path=Path("config.yaml"))
if result.valid:
    print("Config is valid!")
else:
    for error in result.errors:
        print(error)

# With overrides to satisfy _required_ values
result = rc.validate(
    path=Path("config.yaml"),
    overrides={"api_key": "secret123"},
)

# Validate only a section
result = rc.validate(path=Path("trainer.yaml"), inner_path="model")

rc.instantiate(path, expected_type=None, *, inner_path=None, overrides=None, cli_overrides=True, lazy=False)

Load, compose, validate, and instantiate a configuration file into Python objects.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to the configuration file. Accepts str, Path, or any os.PathLike. Supports .yaml, .yml, .json, .toml.
expected_type type[T] \| None None Optional type for type-safe returns. Enables IDE autocompletion and type checking.
inner_path str \| None None Dot-notation path to instantiate only a section (e.g.,"model.encoder" or "trainer.callbacks[0]"). Interpolations are resolved from the full config before extraction. When specified, the root-level _target_ is optional and types can be inferred from parent's type hints (including list[X], set[X], dict[str, X], Sequence[X], Mapping[K, V], tuple[A, B, C], Optional[container], Annotated[X, ...], NewType, and Union[A, B] via structural matching).
overrides dict[str, Any] \| None None Config overrides using dot notation keys. Applied before CLI overrides.
cli_overrides bool True Whether to parse CLI overrides from sys.argv. Set to False for tests or library usage.
lazy bool False If True, all nested configs delay __init__ until first attribute access.

Returns: T if expected_type provided, otherwise Any

Raises:

Exception Condition
ConfigFileError File cannot be loaded or parsed
TargetNotFoundError _target_ value not registered
ValidationError Config structure is invalid
RequiredValueError _required_ value not provided
CircularRefError Circular _ref_ references detected
CircularInstanceError Circular _instance_ references detected
RefResolutionError A _ref_ cannot be resolved
InstanceResolutionError An _instance_ path cannot be resolved
InvalidInnerPathError inner_path doesn't exist in config
InvalidOverridePathError An override path doesn't exist
InvalidOverrideSyntaxError An override string is malformed
InstantiationError Object creation fails

Examples:

# Basic usage - string paths work directly
model = rc.instantiate(path="config.yaml")

# Type-safe with IDE autocompletion
model = rc.instantiate(path="config.yaml", expected_type=ModelConfig)

# Partial instantiation
encoder = rc.instantiate(path="trainer.yaml", inner_path="model.encoder")

# With overrides, no CLI parsing (for tests)
model = rc.instantiate(
    path="config.yaml",
    overrides={"learning_rate": 0.001},
    cli_overrides=False,
)

# Lazy instantiation
app = rc.instantiate(path="app.yaml", lazy=True)

# Path objects also work
from pathlib import Path
model = rc.instantiate(path=Path("config.yaml"))

rc.instantiate_multirun(path, expected_type=None, *, sweep=None, experiments=None, overrides=None, inner_path=None, cli_overrides=True, lazy=False)

Generate and instantiate multiple config combinations from sweep parameters and experiments. See Multirun Support for detailed usage examples.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to the base configuration file. Accepts str, Path, or any os.PathLike.
expected_type type[T] \| None None Optional type for type-safe returns.
sweep dict[str, list[Any]] \| None None Dict of parameter paths to lists of values. All combinations (cartesian product) are generated.
experiments list[dict[str, Any]] \| None None List of explicit experiment override dicts.
overrides dict[str, Any] \| None None Constant overrides applied to all runs (lowest priority).
inner_path str \| None None Dot-notation path to instantiate only a section (e.g., "model"). Interpolations are resolved from the full config before extraction.
cli_overrides bool True Whether to parse CLI overrides from sys.argv.
lazy bool False If True, nested configs delay __init__ until first attribute access.

Returns: MultirunIterator[T] if expected_type provided, otherwise MultirunIterator[Any]

Raises:

Exception Condition
NoRunConfigurationError Neither sweep nor experiments provided
InvalidSweepValueError Sweep values are not lists
InvalidInnerPathError inner_path doesn't exist in config (when accessed)

Examples:

# Sweep with partial instantiation - string paths work directly
for result in rc.instantiate_multirun(
    path="trainer.yaml",
    inner_path="model",
    sweep={"lr": [0.01, 0.001]},
):
    model = result.instance  # Only the model section

# Combined sweep and experiments
for result in rc.instantiate_multirun(
    path="config.yaml",
    experiments=[{"model": "resnet"}, {"model": "vit"}],
    sweep={"lr": [0.01, 0.001]},
):
    train(result.instance)  # 4 runs total

rc.known_targets()

Get a read-only view of all registered configuration references.

Parameters: None

Returns: MappingProxyType[str, TargetEntry] - Immutable mapping of name to TargetEntry

TargetEntry has attributes:

  • name (str): Identifier for the target class
  • target_class (type[Any]): The registered class
  • decisive_init_parameters (MappingProxyType[str, Parameter]): Constructor parameters

Examples:

refs = rc.known_targets()
for name, ref in refs.items():
    print(f"{name}: {ref.target_class}")
    for param_name, param in ref.decisive_init_parameters.items():
        print(f"  {param_name}: {param.annotation}")

rc.get_provenance(path, *, inner_path=None, overrides=None, cli_overrides=True)

Compose a config file and track the origin of each value.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to the entry-point config file. Accepts str, Path, or any os.PathLike.
inner_path str \| None None If specified, returns provenance only for this section. Uses lazy loading.
overrides dict[str, Any] \| None None Dictionary of config overrides using dot notation keys.
cli_overrides bool True Whether to parse CLI overrides from sys.argv. Set to False for tests or library usage.

Returns: Provenance object with methods:

  • get(path: str) -> ProvenanceEntry | None: Get entry for a specific config path
  • items() -> Iterator[tuple[str, ProvenanceEntry]]: Iterate all (path, entry) tuples
  • trace(path: str) -> ProvenanceNode | None: Get full tree for a path
  • to_dict() -> dict: Export as dictionary

Use rc.format(prov) for customized output formatting.

Examples:

# String paths work directly
prov = rc.get_provenance(path="trainer.yaml")
print(prov)  # Default formatting

entry = prov.get("model.layers")
print(f"Defined at: {entry.file}:{entry.line}")

# Custom formatting
print(rc.format(prov).minimal())
print(rc.format(prov).for_path("/model.*"))

# Partial provenance - only loads files needed for model section
prov = rc.get_provenance(path="trainer.yaml", inner_path="model")

# With overrides
prov = rc.get_provenance(
    path=Path("config.yaml"),
    overrides={"model.lr": 0.01}
)

# Disable CLI parsing (for tests/library usage)
prov = rc.get_provenance(path=Path("config.yaml"), cli_overrides=False)

rc.diff(left, right, *, left_inner_path=None, right_inner_path=None, left_overrides=None, right_overrides=None, cli_overrides=False)

Compare two configurations and report differences.

Parameters:

Parameter Type Default Description
left StrOrPath \| Provenance required Left (base) config. Path or existing Provenance object.
right StrOrPath \| Provenance required Right (new) config. Path or existing Provenance object.
left_inner_path str \| None None Dot-notation path to compare only a section of the left config.
right_inner_path str \| None None Dot-notation path to compare only a section of the right config.
left_overrides dict[str, Any] \| None None Overrides for left config (ignored if left is Provenance).
right_overrides dict[str, Any] \| None None Overrides for right config (ignored if right is Provenance).
cli_overrides bool False Whether to parse CLI overrides from sys.argv.

Returns: ConfigDiff - Immutable object with added, removed, changed, unchanged views. Each view is a MappingProxyType[str, DiffEntry].

Use rc.format(diff) for customized output formatting.

Examples:

# Compare two config files
diff = rc.diff(Path("config_v1.yaml"), Path("config_v2.yaml"))

# Compare same file with different overrides
diff = rc.diff(
    Path("config.yaml"),
    Path("config.yaml"),
    left_overrides={"model.lr": 0.001},
    right_overrides={"model.lr": 0.01},
)

# Reuse existing provenance for efficiency
prov_v1 = rc.get_provenance(path="v1.yaml")
prov_v2 = rc.get_provenance(path="v2.yaml")
diff = rc.diff(prov_v1, prov_v2)

# Compare specific sections
diff = rc.diff(
    Path("v1.yaml"), Path("v2.yaml"),
    left_inner_path="model",
    right_inner_path="model",
)

rc.format(obj, layout=None)

Format a Provenance or ConfigDiff object for display. Returns a fluent builder for configuring output via method chaining.

Parameters:

Parameter Type Default Description
obj Provenance \| ConfigDiff required The object to format.
layout ProvenanceLayout \| None None Optional custom layout (Provenance only). Ignored for ConfigDiff.

Returns: ProvenanceFormat when given Provenance, DiffFormat when given ConfigDiff. Both support method chaining for presets, show/hide toggles, filtering, and layout selection.

Raises:

Exception Condition
TypeError If obj is not a Provenance or ConfigDiff

Examples:

# Provenance formatting
prov = rc.get_provenance(path="config.yaml")
print(rc.format(prov).minimal())
print(rc.format(prov).for_path("/model.*").tree())
print(rc.format(prov).full().flat())

# Diff formatting
diff = rc.diff(Path("v1.yaml"), Path("v2.yaml"))
print(rc.format(diff).terminal())
print(rc.format(diff).show_provenance().markdown())
print(rc.format(diff).changes_only().tree())

rc.set_cache_size(size)

Configure the LRU cache for loaded config files.

Parameters:

Parameter Type Default Description
size int required Cache size. Use 0 for unlimited (default behavior).

Returns: None

Examples:

rc.set_cache_size(size=100)  # Cache up to 100 files
rc.set_cache_size(size=0)    # Unlimited (default)

rc.clear_cache()

Clear the config file cache.

Parameters: None

Returns: None

Examples:

rc.clear_cache()

rc.is_lazy_proxy(obj)

Check if an object is an uninitialized lazy proxy.

Parameters:

Parameter Type Default Description
obj Any required Object to check.

Returns: bool - True if object is a lazy proxy that hasn't been initialized yet

Examples:

model = rc.instantiate(path=Path("config.yaml"), lazy=True)
print(rc.is_lazy_proxy(obj=model))  # True
_ = model.hidden_size  # Triggers initialization
print(rc.is_lazy_proxy(obj=model))  # False

rc.force_initialize(obj)

Force initialization of a lazy proxy without accessing attributes. No-op for regular objects.

Parameters:

Parameter Type Default Description
obj Any required Lazy proxy or regular object.

Returns: None

Examples:

model = rc.instantiate(path=Path("config.yaml"), lazy=True)
rc.force_initialize(obj=model)  # model.__init__ called now
print(rc.is_lazy_proxy(obj=model))  # False

rc.to_dict(path, *, overrides=None, cli_overrides=True, exclude_markers=False)

Export resolved config as a Python dictionary.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to config file. Accepts str, Path, or any os.PathLike.
overrides dict[str, Any] \| None None Dictionary of config overrides.
cli_overrides bool True Whether to parse CLI overrides.
exclude_markers bool False If True, remove internal markers (_target_, _ref_, _instance_, _lazy_).

Returns: dict[str, Any] - Resolved config as a dictionary

Examples:

config = rc.to_dict(path=Path("config.yaml"))
clean = rc.to_dict(path=Path("config.yaml"), exclude_markers=True)

rc.to_yaml(path, *, overrides=None, cli_overrides=True, exclude_markers=False)

Export resolved config as a YAML string.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to config file. Accepts str, Path, or any os.PathLike.
overrides dict[str, Any] \| None None Dictionary of config overrides.
cli_overrides bool True Whether to parse CLI overrides.
exclude_markers bool False If True, remove internal markers.

Returns: str - Resolved config as a YAML string

Examples:

yaml_str = rc.to_yaml(path=Path("config.yaml"))

rc.to_json(path, *, overrides=None, cli_overrides=True, exclude_markers=False, indent=2)

Export resolved config as a JSON string.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to config file. Accepts str, Path, or any os.PathLike.
overrides dict[str, Any] \| None None Dictionary of config overrides.
cli_overrides bool True Whether to parse CLI overrides.
exclude_markers bool False If True, remove internal markers.
indent int \| None 2 Number of spaces for indentation.None for compact output.

Returns: str - Resolved config as a JSON string

Examples:

json_str = rc.to_json(path=Path("config.yaml"))
compact = rc.to_json(path=Path("config.yaml"), indent=None)

rc.to_toml(path, *, overrides=None, cli_overrides=True, exclude_markers=False)

Export resolved config as a TOML string.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to config file. Accepts str, Path, or any os.PathLike.
overrides dict[str, Any] \| None None Dictionary of config overrides.
cli_overrides bool True Whether to parse CLI overrides.
exclude_markers bool False If True, remove internal markers.

Returns: str - Resolved config as a TOML string

Examples:

toml_str = rc.to_toml(path=Path("config.yaml"))

rc.to_file(source, output_path, *, overrides=None, cli_overrides=True, exclude_markers=False)

Export config to a single file with format auto-detected from output path extension.

Parameters:

Parameter Type Default Description
source StrOrPath \| dict[str, Any] required Path to config file, or dict. Accepts str, Path, or any os.PathLike.
output_path StrOrPath required Output file path. Extension determines format (.yaml, .json, .toml).
overrides dict[str, Any] \| None None Config overrides. Ignored if source is dict.
cli_overrides bool True Parse CLI overrides. Ignored if source is dict.
exclude_markers bool False If True, remove internal markers.

Returns: None

Raises:

Exception Condition
ConfigFileError Output file extension not supported

Examples:

# From file path
rc.to_file(source=Path("config.yaml"), output_path=Path("output.json"))

# From dict
config = {"model": {"lr": 0.01}, "epochs": 10}
rc.to_file(source=config, output_path=Path("output.yaml"))

rc.to_files(source, config_root_file, *, overrides=None, cli_overrides=True, exclude_markers=False)

Export config preserving file structure (with _ref_ relationships).

Parameters:

Parameter Type Default Description
source StrOrPath \| dict[str, Any] required Path to config file, or dict. Accepts str, Path, or any os.PathLike.
config_root_file StrOrPath required Output root file path. Extension determines root format.
overrides dict[str, Any] \| None None Config overrides. Ignored if source is dict.
cli_overrides bool True Parse CLI overrides. Ignored if source is dict.
exclude_markers bool False If True, remove internal markers.

Returns: None

Behavior:

  • Root file format determined by config_root_file extension
  • Referenced files preserve their original formats
  • When source is dict, only root file is written

Examples:

rc.to_files(source=Path("trainer.yaml"), config_root_file=Path("output/trainer.json"))
# Creates:
#   output/trainer.json (root in JSON)
#   output/models/resnet.yaml (preserves YAML)

rc.export(path, exporter, *, overrides=None, cli_overrides=True)

Export resolved config using a custom exporter.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to config file. Accepts str, Path, or any os.PathLike.
exporter Exporter required Exporter instance to use.
overrides dict[str, Any] \| None None Dictionary of config overrides.
cli_overrides bool True Parse CLI overrides.

Returns: The exported data in the exporter's target format

Examples:

class MyExporter(Exporter):
    def export(self, config: dict) -> str:
        return json.dumps(config)

result = rc.export(path=Path("config.yaml"), exporter=MyExporter())

@rc.resolver(*path)

Decorator to register a resolver function for use in interpolation expressions.

Parameters:

Parameter Type Default Description
*path str required Path components. Accepts multiple arguments ("db", "lookup") or a single delimited string ("db:lookup" or "db.lookup").

Returns: Decorator function

Special Parameters (in decorated function):

  • _config_ (dict): Keyword-only parameter that receives read-only view of current config

Examples:

# All equivalent ways to register "db:lookup":
@rc.resolver("db", "lookup")
def lookup1(table: str, id: int) -> dict:
    return database.get(table, id)

@rc.resolver("db:lookup")
def lookup2(table: str, id: int) -> dict:
    return database.get(table, id)

@rc.resolver("db.lookup")
def lookup3(table: str, id: int) -> dict:
    return database.get(table, id)

# Simple resolver
@rc.resolver("uuid")
def gen_uuid() -> str:
    import uuid
    return str(uuid.uuid4())

# Resolver with config access
@rc.resolver("derive")
def derive(path: str, *, _config_: dict) -> Any:
    return _config_.get(path)

rc.register_resolver(*path, func)

Register a custom resolver function for use in interpolation expressions.

Parameters:

Parameter Type Default Description
*path str required Path components. Accepts multiple arguments ("db", "lookup") or a single delimited string ("db:lookup" or "db.lookup").
func Callable[..., Any] required The resolver function to register.

Returns: None

Raises:

Exception Condition
ValueError If path is empty or func is not callable

Examples:

def gen_uuid() -> str:
    import uuid
    return str(uuid.uuid4())

# All equivalent:
rc.register_resolver("uuid", func=gen_uuid)
rc.register_resolver("db", "lookup", func=my_lookup)
rc.register_resolver("db:lookup", func=my_lookup)
rc.register_resolver("db.lookup", func=my_lookup)

rc.unregister_resolver(*path)

Unregister a previously registered resolver.

Parameters:

Parameter Type Default Description
*path str required Path components. Accepts multiple arguments ("db", "lookup") or a single delimited string ("db:lookup" or "db.lookup").

Returns: None

Raises:

Exception Condition
KeyError No resolver with that path exists

Examples:

rc.unregister_resolver("uuid")

# All equivalent ways to unregister "db:lookup":
rc.unregister_resolver("db", "lookup")
rc.unregister_resolver("db:lookup")
rc.unregister_resolver("db.lookup")

rc.set_help_integration(integration)

Set a custom help integration for CLI help display.

Parameters:

Parameter Type Default Description
integration HelpIntegration required A HelpIntegration instance to use.

Returns: None

Raises:

Exception Condition
ValueError If integration is None.

Examples:

from rconfig import GroupedHelpIntegration

rc.set_help_integration(GroupedHelpIntegration())

rc.current_help_integration()

Get the current help integration.

Parameters: None

Returns: HelpIntegration - The current integration (default: FlatHelpIntegration)

Examples:

integration = rc.current_help_integration()
print(type(integration))  # <class 'rconfig.help.FlatHelpIntegration'>

@rc.help_integration

Decorator to register a function as the help integration.

The decorated function receives (provenance, config_path) and is responsible for all behavior including calling sys.exit() if needed.

Parameters:

Parameter Type Default Description
func Callable[[Provenance, str], None] required Function to handle help display.

Returns: The same function (for use as decorator)

Examples:

@rc.help_integration
def my_help(provenance, config_path):
    print(f"Help for {config_path}")
    for path, entry in provenance.items():
        print(f"  {path}: {entry.type_hint}")
    sys.exit(0)

@rc.on_config_loaded(*, pattern=None, priority=50)

Decorator to register a hook called after config composition, before instantiation.

Hooks can optionally return a dict to modify the config. If a hook returns None (or doesn't return), the config is unchanged. Multiple hooks chain modifications in priority order.

Parameters:

Parameter Type Default Description
pattern str \| None None Glob pattern for conditional execution.
priority int 50 Execution order (lower values run first).

Returns: The decorated function.

Examples:

from rconfig.hooks import HookContext

@rc.on_config_loaded
def validate_paths(ctx: HookContext) -> None:
    """Validate data paths exist."""
    if ctx.config and "data_path" in ctx.config:
        path = Path(ctx.config["data_path"])
        if not path.exists():
            raise ValueError(f"Data path not found: {path}")

@rc.on_config_loaded(pattern="**/model/*.yaml", priority=10)
def model_hook(ctx: HookContext) -> None:
    """Only runs for model configs, runs early."""
    ...

@rc.on_config_loaded
def inject_secrets(ctx: HookContext) -> dict | None:
    """Modify config by returning a new dict."""
    if ctx.config.get("api_key") == "_required_":
        return {**ctx.config, "api_key": os.getenv("API_KEY")}
    return None  # No changes

@rc.on_before_instantiate(*, pattern=None, priority=50)

Decorator to register a hook called before each object's constructor.

Parameters:

Parameter Type Default Description
pattern str \| None None Glob pattern for conditional execution.
priority int 50 Execution order (lower values run first).

Returns: The decorated function.

Examples:

@rc.on_before_instantiate
def log_instantiation(ctx: HookContext) -> None:
    print(f"Creating {ctx.target_name} at {ctx.inner_path}")

@rc.on_after_instantiate(*, pattern=None, priority=50)

Decorator to register a hook called after each object's constructor returns.

Parameters:

Parameter Type Default Description
pattern str \| None None Glob pattern for conditional execution.
priority int 50 Execution order (lower values run first).

Returns: The decorated function.

Examples:

@rc.on_after_instantiate
def register_metrics(ctx: HookContext) -> None:
    metrics.register(ctx.target_name, ctx.instance)

@rc.on_error(*, pattern=None, priority=50)

Decorator to register a hook called when instantiation fails.

Parameters:

Parameter Type Default Description
pattern str \| None None Glob pattern for conditional execution.
priority int 50 Execution order (lower values run first).

Returns: The decorated function.

Examples:

@rc.on_error
def log_failures(ctx: HookContext) -> None:
    logger.error(f"Instantiation failed: {ctx.error}")

rc.register_hook(phase, func, *, name=None, pattern=None, priority=50)

Explicitly register a hook function for a specific phase.

Parameters:

Parameter Type Default Description
phase HookPhase required The lifecycle phase to register for.
func Callable required The hook function.
name str \| None None Hook name (defaults to function name).
pattern str \| None None Glob pattern for conditional execution.
priority int 50 Execution order (lower values run first).

Returns: None

Examples:

from rconfig.hooks import HookPhase

def my_hook(ctx: HookContext) -> None:
    print(f"Config loaded: {ctx.config_path}")

rc.register_hook(HookPhase.CONFIG_LOADED, my_hook, name="my_hook")

rc.unregister_hook(name, *, phase=None)

Remove a registered hook by name.

Parameters:

Parameter Type Default Description
name str required Name of the hook to remove.
phase HookPhase \| None None If specified, only remove from this phase.

Returns: None

Raises:

Exception Condition
KeyError If no hook with that name exists

Examples:

rc.unregister_hook("my_hook")
rc.unregister_hook("my_hook", phase=HookPhase.CONFIG_LOADED)

rc.register_callback(callback)

Register a Callback class instance. All implemented methods are registered as hooks.

Parameters:

Parameter Type Default Description
callback Callback required Instance of a Callback subclass

Returns: None

Examples:

class ExperimentTracker(rc.Callback):
    def on_config_loaded(self, ctx: HookContext) -> None:
        self.run_id = start_run()
        log_config(self.run_id, dict(ctx.config))

    def on_after_instantiate(self, ctx: HookContext) -> None:
        log_component(self.run_id, ctx.target_name)

tracker = ExperimentTracker()
rc.register_callback(tracker)

rc.unregister_callback(callback)

Remove all hooks registered by a Callback instance.

Parameters:

Parameter Type Default Description
callback Callback required The Callback instance to remove

Returns: None

Examples:

rc.unregister_callback(tracker)

rc.known_hooks()

Return a read-only view of all registered hooks.

Parameters: None

Returns: MappingProxyType[HookPhase, tuple[HookEntry, ...]]

Examples:

for phase, hooks in rc.known_hooks().items():
    for hook in hooks:
        print(f"{phase.name}: {hook.name} (priority={hook.priority})")

Common Types

Types returned by common API functions.

ValidationResult

Result of config validation, returned by rc.validate().

Attributes:

Attribute Type Description
valid bool True if validation passed with no errors
errors list[ValidationError] List of validation errors (empty if valid=True)

Examples:

result = rc.validate(path="config.yaml")
if not result.valid:
    for error in result.errors:
        print(error)

ConfigDiff

Immutable diff result, returned by rc.diff(). Acts as a mapping of config paths to DiffEntry objects.

Attributes:

Attribute Type Description
added MappingProxyType[str, DiffEntry] Entries present only in right
removed MappingProxyType[str, DiffEntry] Entries present only in left
changed MappingProxyType[str, DiffEntry] Entries with different values
unchanged MappingProxyType[str, DiffEntry] Entries with identical values

Methods:

Method Returns Description
is_empty() bool True if no added/removed/changed
to_dict() dict[str, Any] Export as dictionary
__len__() int Total entry count
__contains__(path) bool Check if path exists in diff
__getitem__(path) DiffEntry Get entry by config path

DiffEntry

A single entry in a ConfigDiff.

Attributes:

Attribute Type Description
path str Config path (e.g., "model.lr")
diff_type DiffEntryType One of: ADDED, REMOVED, CHANGED, UNCHANGED
left_value Any Value in left config (None if added)
right_value Any Value in right config (None if removed)
left_provenance ProvenanceEntry \| None Provenance entry from left config
right_provenance ProvenanceEntry \| None Provenance entry from right config

ProvenanceNode

Immutable node in a provenance trace tree, returned by prov.trace(path). Forms a tree structure for tracing compound expressions through refs, interpolations, operators, and resolvers.

Attributes:

Attribute Type Description
source_type NodeSourceType Type of this node (file, ref, interpolation, etc.)
path str \| None Config path (e.g., "/model.lr")
file str \| None Source file name
line int \| None Line number in source file
value Any The resolved value at this node
expression str \| None Interpolation expression (e.g., "${/a + /b}")
operator str \| None Operator for compound expressions (+, *, etc.)
env_var str \| None Environment variable name (for env sources)
cli_arg str \| None CLI argument (for CLI sources)
resolver_name str \| None Resolver path (e.g., "uuid", "db:lookup")
resolver_func str \| None Function name of the resolver
resolver_module str \| None Module where the resolver is defined
children tuple[ProvenanceNode, ...] Child nodes in the tree

Methods:

Method Returns Description
to_dict() dict[str, Any] Recursively convert to dictionary

Examples:

prov = rc.get_provenance(path="config.yaml")
tree = prov.trace("model.lr")
if tree:
    print(tree.source_type)  # "file", "interpolation", etc.
    print(tree.file, tree.line)
    for child in tree.children:
        print(f"  {child.source_type}: {child.path}")
    # Export as dict
    data = tree.to_dict()

NodeSourceType

Enum (StrEnum) indicating the type of each node in a provenance trace tree.

Values:

Value Description
FILE Value came from a config file
REF Value came from a _ref_ reference
INSTANCE Value came from an instance chain
INTERPOLATION Value was computed via interpolation
CLI Value was set via command-line argument
ENV Value was set via environment variable
PROGRAMMATIC Value was set programmatically
OPERATOR Value is result of an operator expression
RESOLVER Value came from a resolver function

Advanced API

Classes and types for extending and customizing rconfig. Use these when you need to create custom loaders, exporters, or help integrations.

Multirun Types

MultirunResult

Result of a single multirun instantiation. Contains the immutable resolved config, the specific overrides applied for this run, and the instantiated object (or stored error).

Attributes:

Attribute Type Description
config MappingProxyType[str, Any] Immutable view of the resolved config
overrides MappingProxyType[str, Any] The specific overrides for this run
instance T The instantiated object (property)

Notes:

  • instance is a property that raises any stored error when accessed
  • Use try/except for graceful error handling per run

Examples:

for result in rc.instantiate_multirun(...):
    # Fail fast - raises if this run failed
    train(result.instance)

    # Or handle errors individually
    try:
        train(result.instance)
    except (ValidationError, InstantiationError) as e:
        log_failure(result.overrides, e)

MultirunIterator

Lazy iterator with length and slicing support for multirun results. Enables efficient iteration with progress tracking.

Methods:

Method Returns Description
__len__() int Total number of runs
__iter__() MultirunIterator[T] Fresh iterator from beginning
__reversed__() MultirunIterator[T] Iterator in reverse order
__getitem__(i) MultirunResult[T] Access single run by index
__getitem__(s) MultirunIterator[T] Slice to get subset iterator

Examples:

results = rc.instantiate_multirun(...)

# Progress tracking with tqdm
for result in tqdm(results):
    train(result.instance)

# Resume from crash point
for result in results[50:]:
    train(result.instance)

# Distribute across workers
worker1_results = results[0:25]
worker2_results = results[25:50]

# Debug specific run
single_result = results[3]

MULTIRUN_HELP

Help text constant for multirun CLI options. Use this to include multirun documentation in your CLI help.

Type: str

Example:

import argparse
from rconfig import MULTIRUN_HELP

parser = argparse.ArgumentParser(
    epilog=MULTIRUN_HELP,
    formatter_class=argparse.RawDescriptionHelpFormatter
)

MultirunError

Base exception for multirun-related errors.

InvalidSweepValueError

Raised when sweep values are not lists.

NoRunConfigurationError

Raised when neither sweep nor experiments is provided to instantiate_multirun().

Help Integration Classes

HelpIntegration

Abstract base class for CLI help integrations. Subclass this to customize how config help is integrated into CLI.

Constructor:

Parameter Type Default Description
consume_help_flag bool True If True, remove --help/-h from sys.argv.

Abstract Methods:

Method Description
integrate(provenance, config_path) Called when --help/-h is detected.

Examples:

from rconfig import HelpIntegration

class CustomHelpIntegration(HelpIntegration):
    def integrate(self, provenance, config_path):
        print(f"Custom help for {config_path}")
        for path, entry in provenance.items():
            print(f"  {path}: {entry.value}")
        sys.exit(0)

rc.set_help_integration(CustomHelpIntegration())

FlatHelpIntegration

Displays config entries as a flat aligned table. This is the default integration.

Constructor:

Parameter Type Default Description
output TextIO \| None sys.stdout Output stream.

Output format:

Configuration options for config.yaml
=====================================

model.lr              float       0.001      Learning rate
model.hidden_size     int         256        Hidden layer size
data.path             str         (required) Path to data

GroupedHelpIntegration

Displays config entries grouped by top-level key with indentation.

Constructor:

Parameter Type Default Description
output TextIO \| None sys.stdout Output stream.

Output format:

Configuration options for config.yaml
=====================================

model:
  lr                  float       0.001      Learning rate
  hidden_size         int         256        Hidden layer size
data:
  path                str         (required) Path to data

Examples:

from rconfig import GroupedHelpIntegration

rc.set_help_integration(GroupedHelpIntegration())

ArgparseHelpIntegration

Integrates config entries into argparse help output. Adds config entries to the parser's epilog.

Constructor:

Parameter Type Default Description
parser argparse.ArgumentParser required The argparse parser to integrate.

Notes:

  • Uses consume_help_flag=False because argparse handles --help itself

Examples:

import argparse
from rconfig import ArgparseHelpIntegration

parser = argparse.ArgumentParser()
parser.add_argument("--verbose", action="store_true")

rc.set_help_integration(ArgparseHelpIntegration(parser))
args = parser.parse_args()
config = rc.instantiate(Path("config.yaml"))

Exporter Registry

rc.register_exporter(exporter, *extensions)

Register an exporter for specific file extensions.

Parameters:

Parameter Type Default Description
exporter Exporter required Exporter instance to register.
*extensions str required Extensions to register (e.g., ".xml", ".protobuf").

Returns: None

Examples:

class XmlExporter(Exporter):
    def export(self, config: dict) -> str:
        return dict_to_xml(config)

rc.register_exporter(XmlExporter(), ".xml")

rc.unregister_exporter(extension)

Unregister an exporter by extension.

Parameters:

Parameter Type Default Description
extension str required The extension to unregister.

Returns: None

Raises:

Exception Condition
KeyError Extension not registered

Examples:

rc.unregister_exporter(extension=".xml")

rc.get_exporter(path)

Get the appropriate exporter for a config file based on its extension.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to the config file. Accepts str, Path, or any os.PathLike.

Returns: Exporter - An exporter instance for the file format

Raises:

Exception Condition
ConfigFileError If no exporter supports the file format.

Examples:

exporter = rc.get_exporter(Path("config.yaml"))
result = exporter.export(config_dict)

rc.supported_exporter_extensions()

Get all supported export file extensions.

Parameters: None

Returns: frozenset[str] - Supported extensions (lowercase, e.g., {'.yaml', '.json', '.toml'})

Examples:

extensions = rc.supported_exporter_extensions()
# frozenset({'.yaml', '.yml', '.json', '.toml'})

Exporter Classes

Exporter

Abstract base class for config exporters. Subclass this to create custom exporters.

Abstract Methods:

Method Returns Description
export(config: dict) Any Export config to the target format

Examples:

from rconfig import Exporter

class XmlExporter(Exporter):
    def export(self, config: dict) -> str:
        return dict_to_xml(config)

rc.register_exporter(XmlExporter(), ".xml")

YamlExporter

Export config as a YAML string.

Constructor:

Parameter Type Default Description
default_flow_style bool \| None False None=block, True=flow, False=mixed
indent int 2 Indentation spaces
exclude_markers bool False Remove internal markers
markers tuple[str, ...] (default) Marker keys to exclude

JsonExporter

Export config as a JSON string.

Constructor:

Parameter Type Default Description
indent int \| None 2 Indentation (None for compact)
ensure_ascii bool False Escape non-ASCII characters
sort_keys bool False Sort dictionary keys
exclude_markers bool False Remove internal markers
markers tuple[str, ...] (default) Marker keys to exclude

TomlExporter

Export config as a TOML string.

Constructor:

Parameter Type Default Description
multiline_strings bool False Use multiline for strings
exclude_markers bool False Remove internal markers
markers tuple[str, ...] (default) Marker keys to exclude

DictExporter

Export config as a Python dictionary. This is the base exporter used internally.

FileExporter

Base class for file-based exporters. Subclass this to create exporters that write to files.

SingleFileExporter

Export config to a single file. Used by rc.to_file().

MultiFileExporter

Export config preserving _ref_ structure across multiple files. Used by rc.to_files().

Loader Registry

rc.register_loader(loader, *extensions)

Register a config file loader for specific extensions.

Parameters:

Parameter Type Default Description
loader ConfigFileLoader required A ConfigFileLoader instance to register.
*extensions str required Extensions to register (e.g., ".ini", ".conf").

Returns: None

Examples:

class IniConfigLoader(ConfigFileLoader):
    def load(self, path: Path) -> dict[str, Any]:
        import configparser
        parser = configparser.ConfigParser()
        parser.read(path)
        return {s: dict(parser[s]) for s in parser.sections()}

    def load_with_positions(self, path: Path) -> PositionMap:
        return PositionMap(self.load(path))

rc.register_loader(IniConfigLoader(), ".ini")

rc.unregister_loader(extension)

Unregister a config file loader by extension.

Parameters:

Parameter Type Default Description
extension str required The extension to unregister.

Returns: None

Raises:

Exception Condition
KeyError Extension not registered

Examples:

rc.unregister_loader(extension=".ini")

rc.get_loader(path)

Get the appropriate loader for a config file based on its extension.

Parameters:

Parameter Type Default Description
path StrOrPath required Path to the config file. Accepts str, Path, or any os.PathLike.

Returns: ConfigFileLoader - A loader instance for the file format

Raises:

Exception Condition
ConfigFileError If no loader supports the file format.

Examples:

loader = rc.get_loader(Path("config.yaml"))
config_dict = loader.load(Path("config.yaml"))

rc.supported_loader_extensions()

Get all supported loader file extensions.

Parameters: None

Returns: frozenset[str] - Supported extensions (lowercase, e.g., {'.yaml', '.yml', '.json', '.toml'})

Examples:

extensions = rc.supported_loader_extensions()

Loader Classes

ConfigFileLoader

Abstract base class for config file loaders. Subclass this to support additional file formats.

Abstract Methods:

Method Returns Description
load(path: Path) dict Load config as dictionary
load_with_positions(path) PositionMap Load with line/column position info

Examples:

from rconfig import ConfigFileLoader

class IniConfigLoader(ConfigFileLoader):
    def load(self, path: Path) -> dict:
        import configparser
        parser = configparser.ConfigParser()
        parser.read(path)
        return {s: dict(parser[s]) for s in parser.sections()}

    def load_with_positions(self, path: Path) -> PositionMap:
        return PositionMap(self.load(path))

rc.register_loader(IniConfigLoader(), ".ini")

YamlConfigLoader

Load YAML config files using ruamel.yaml.

Supported Extensions: .yaml, .yml

JsonConfigLoader

Load JSON config files using Python's standard library.

Supported Extensions: .json

TomlConfigLoader

Load TOML config files using Python 3.11+ tomllib.

Supported Extensions: .toml

Deprecation Classes

DeprecationInfo

Information about a deprecated key.

Attributes:

Attribute Type Description
old_key str The deprecated key path
new_key str \| None Migration target (if any)
message str \| None Custom deprecation message
remove_in str \| None Version when key will be removed
policy str \| None Override policy (warn/error/ignore)

DeprecationHandler

Abstract base class for custom deprecation warning handlers.

Abstract Methods:

Method Description
handle(info, path, file, line) Called when deprecated key used

Examples:

from rconfig import DeprecationHandler, DeprecationInfo

class LoggingHandler(DeprecationHandler):
    def handle(self, info: DeprecationInfo, path: str, file: str, line: int) -> None:
        import logging
        logging.warning(f"Deprecated key '{path}' at {file}:{line}")

rc.set_deprecation_handler(LoggingHandler())

DeprecatedKeyError

Exception raised when a deprecated key is used and the deprecation policy is set to "error".

RconfigDeprecationWarning

Warning class used by the default deprecation handler. Integrates with Python's warnings filter system.

Hook Classes

rc.Callback

Base class for class-based hooks that can maintain state across hook invocations.

Methods to Override:

Method Phase Description
on_config_loaded(ctx) CONFIG_LOADED Called after config composition
on_before_instantiate(ctx) BEFORE_INSTANTIATE Called before each constructor
on_after_instantiate(ctx) AFTER_INSTANTIATE Called after each constructor
on_error(ctx) ON_ERROR Called when instantiation fails

Examples:

class ExperimentTracker(rc.Callback):
    def __init__(self, tracking_uri: str):
        self.tracking_uri = tracking_uri
        self.run_id = None

    def on_config_loaded(self, ctx: HookContext) -> None:
        self.run_id = start_run(self.tracking_uri)
        log_config(self.run_id, dict(ctx.config))

    def on_after_instantiate(self, ctx: HookContext) -> None:
        log_component(self.run_id, ctx.target_name, ctx.instance)

    def on_error(self, ctx: HookContext) -> None:
        mark_failed(self.run_id, str(ctx.error))

tracker = ExperimentTracker("http://mlflow.internal")
rc.register_callback(tracker)

HookPhase

Enum defining the lifecycle phases where hooks can be registered.

Values:

Value Description
CONFIG_LOADED After config composition, before instantiation
BEFORE_INSTANTIATE Before each object's constructor call
AFTER_INSTANTIATE After each object's constructor returns
ON_ERROR When instantiation fails with an exception

HookContext

Immutable context object passed to hook functions.

Attributes:

Attribute Type Available In Description
phase HookPhase All Current lifecycle phase
config_path str All Path to the config file
config MappingProxyType or None All Read-only view of config dict
inner_path str \| None BEFORE/AFTER_INSTANTIATE Path within config
target_name str \| None BEFORE/AFTER_INSTANTIATE The _target_ name
instance Any \| None AFTER_INSTANTIATE The instantiated object
error Exception \| None ON_ERROR The exception that occurred

HookEntry

Immutable dataclass representing a registered hook.

Attributes:

Attribute Type Description
name str Hook identifier
phase HookPhase Lifecycle phase
func Callable The hook function
pattern str \| None Glob pattern for conditional execution
priority int Execution order (lower runs first)

HookError

Base exception for hook-related errors.

HookExecutionError

Exception raised when a hook function raises an error during execution.

Attributes:

Attribute Type Description
hook_name str Name of the failing hook
phase HookPhase Phase when error occurred
original_error Exception The original exception