Configuration Diff

Advanced configuration diff and drift detection for Confii.

This module provides comprehensive diff functionality and drift detection to compare configurations and detect discrepancies.

class confii.config_diff.ConfigDiff(key: str, diff_type: DiffType, old_value: Any = None, new_value: Any = None, path: str = '')[source]

Bases: object

Represents a difference between two configurations.

This class encapsulates a single difference between two configuration dictionaries, including the key, type of change, and both old and new values.

key

The configuration key that differs (e.g., β€œhost”)

diff_type

Type of difference (ADDED, REMOVED, MODIFIED, UNCHANGED)

old_value

Original value in the first configuration

new_value

New value in the second configuration

path

Full dot-separated path to the key (e.g., β€œdatabase.host”)

nested_diffs

List of nested ConfigDiff objects for complex nested changes

Example

>>> diff = ConfigDiff(
...     key="host",
...     diff_type=DiffType.MODIFIED,
...     old_value="localhost",
...     new_value="remote",
...     path="database.host",
... )
>>> print(f"{diff.path}: {diff.diff_type.value}")
database.host: modified
__init__(key: str, diff_type: DiffType, old_value: Any = None, new_value: Any = None, path: str = '') None[source]

Initialize a configuration diff.

Parameters:
  • key – Configuration key that differs

  • diff_type – Type of difference (ADDED, REMOVED, MODIFIED, UNCHANGED)

  • old_value – Original value in the first configuration

  • new_value – New value in the second configuration

  • path – Full dot-separated path to the key (for nested configurations)

__repr__() str[source]

String representation of the diff.

to_dict() Dict[str, Any][source]

Convert diff to dictionary representation.

Returns:

Dictionary representation of the diff

class confii.config_diff.ConfigDiffer[source]

Bases: object

Advanced configuration differ with structured diff output.

This class provides utilities for comparing two configurations and generating structured diff results. It supports nested configurations and provides detailed information about all differences.

Example

>>> config1 = {"database": {"host": "localhost", "port": 5432}}
>>> config2 = {"database": {"host": "remote", "port": 5432, "ssl": True}}
>>> diffs = ConfigDiffer.diff(config1, config2)
>>> summary = ConfigDiffer.diff_summary(diffs)
>>> print(f"Found {summary['total']} differences")
static diff(config1: Dict[str, Any], config2: Dict[str, Any], path: str = '') List[ConfigDiff][source]

Generate structured diff between two configurations.

Parameters:
  • config1 – First configuration dictionary

  • config2 – Second configuration dictionary

  • path – Current path prefix (for nested keys)

Returns:

List of ConfigDiff objects representing all differences

Example

>>> config1 = {"database": {"host": "localhost"}}
>>> config2 = {"database": {"host": "remote"}}
>>> diffs = ConfigDiffer.diff(config1, config2)
>>> diffs[0].key  # 'host'
>>> diffs[0].diff_type  # DiffType.MODIFIED
static diff_summary(diffs: List[ConfigDiff]) Dict[str, Any][source]

Generate summary of differences.

Parameters:

diffs – List of ConfigDiff objects

Returns:

Dictionary with summary statistics

static diff_to_json(diffs: List[ConfigDiff], indent: int = 2) str[source]

Convert diff list to JSON string.

Parameters:
  • diffs – List of ConfigDiff objects

  • indent – JSON indentation level

Returns:

JSON string representation

class confii.config_diff.ConfigDriftDetector(intended_config: Dict[str, Any])[source]

Bases: object

Detects configuration drift (intended vs. actual state).

Configuration drift occurs when the actual configuration differs from the intended or target configuration. This class helps identify such discrepancies, which is useful for compliance, auditing, and troubleshooting.

intended_config

The intended/target configuration state

Example

>>> intended = {"database": {"host": "prod-db.example.com"}}
>>> actual = {"database": {"host": "dev-db.example.com"}}
>>> detector = ConfigDriftDetector(intended)
>>> drift = detector.detect_drift(actual)
>>> if drift:
...     print(f"Configuration drift detected: {len(drift)} differences")
...     for diff in drift:
...         print(
...             f"  {diff.path}: expected {diff.old_value}, got {diff.new_value}"
...         )

See also

ConfigDiffer: For comparing two arbitrary configurations

__init__(intended_config: Dict[str, Any]) None[source]

Initialize drift detector.

Parameters:

intended_config – The intended/target configuration state

detect_drift(actual_config: Dict[str, Any]) List[ConfigDiff][source]

Detect drift between intended and actual configuration.

Parameters:

actual_config – The actual current configuration

Returns:

List of ConfigDiff objects representing drift

Example

>>> detector = ConfigDriftDetector(intended_config)
>>> drift = detector.detect_drift(actual_config)
>>> if drift:
...     print(f"Configuration drift detected: {len(drift)} differences")
has_drift(actual_config: Dict[str, Any]) bool[source]

Check if drift exists without generating full diff.

Parameters:

actual_config – The actual current configuration

Returns:

True if drift detected, False otherwise

class confii.config_diff.DiffType(*values)[source]

Bases: Enum

Types of configuration differences.

ADDED = 'added'
MODIFIED = 'modified'
REMOVED = 'removed'
UNCHANGED = 'unchanged'