Skip to content

API Reference

This page is auto-generated from Python docstrings.

composable_data_core

Composable Data Core.

A small typed decision grammar for analytical work.

Evaluation dataclass

Record metric results computed elsewhere.

Source code in src/composable_data_core/evaluation.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@dataclass(frozen=True, slots=True)
class Evaluation:
    """Record metric results computed elsewhere."""

    model_id: str
    metrics: Mapping[str, float]

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not self.model_id.strip():
            raise ValueError("model_id must not be empty.")
        if not self.metrics:
            raise ValueError("Evaluation must contain at least one metric.")
        object.__setattr__(self, "metrics", MappingProxyType(dict(self.metrics)))

__post_init__

__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/evaluation.py
15
16
17
18
19
20
21
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not self.model_id.strip():
        raise ValueError("model_id must not be empty.")
    if not self.metrics:
        raise ValueError("Evaluation must contain at least one metric.")
    object.__setattr__(self, "metrics", MappingProxyType(dict(self.metrics)))

ExperimentAssessment dataclass

Record the conclusion drawn from comparable experiment evidence.

Source code in src/composable_data_core/experiment_assessment.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@dataclass(frozen=True, slots=True)
class ExperimentAssessment:
    """Record the conclusion drawn from comparable experiment evidence."""

    comparison: str
    conclusion: str
    rationale: Rationale
    winner_model_id: str | None = None
    baseline_beaten: bool | None = None

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not self.comparison.strip():
            raise ValueError("Comparison description must not be empty.")
        if not self.conclusion.strip():
            raise ValueError("Conclusion must not be empty.")

__post_init__

__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/experiment_assessment.py
18
19
20
21
22
23
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not self.comparison.strip():
        raise ValueError("Comparison description must not be empty.")
    if not self.conclusion.strip():
        raise ValueError("Conclusion must not be empty.")

ExperimentSpec dataclass

Declare a complete analytical experiment before execution.

Source code in src/composable_data_core/experiment_spec.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
@dataclass(frozen=True, slots=True)
class ExperimentSpec[DatasetRefT]:
    """Declare a complete analytical experiment before execution."""

    dataset: DatasetRefT

    grain: Grain
    learning_mode: LearningMode
    problem_type: ProblemType

    target: str
    selected_features: tuple[str, ...]
    feature_rationale: Rationale

    resolution: Resolution
    split: SplitPlan

    baseline_id: str
    baseline: ModelPlan

    candidate_id: str
    candidate: ModelPlan

    def __post_init__(self) -> None:
        """Validate the experiment specification."""
        if not self.target.strip():
            raise ValueError("Target must not be empty.")

        if not self.selected_features:
            raise ValueError("Selected features must not be empty.")

        if self.target in self.selected_features:
            raise ValueError("Target must not also appear in selected features.")

        if not self.baseline_id.strip():
            raise ValueError("Baseline ID must not be empty.")

        if not self.candidate_id.strip():
            raise ValueError("Candidate ID must not be empty.")

        if self.baseline_id == self.candidate_id:
            raise ValueError("Baseline and candidate IDs must be different.")

__post_init__

__post_init__() -> None

Validate the experiment specification.

Source code in src/composable_data_core/experiment_spec.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def __post_init__(self) -> None:
    """Validate the experiment specification."""
    if not self.target.strip():
        raise ValueError("Target must not be empty.")

    if not self.selected_features:
        raise ValueError("Selected features must not be empty.")

    if self.target in self.selected_features:
        raise ValueError("Target must not also appear in selected features.")

    if not self.baseline_id.strip():
        raise ValueError("Baseline ID must not be empty.")

    if not self.candidate_id.strip():
        raise ValueError("Candidate ID must not be empty.")

    if self.baseline_id == self.candidate_id:
        raise ValueError("Baseline and candidate IDs must be different.")

Grain dataclass

Declare what one observation represents.

Source code in src/composable_data_core/grain.py
 6
 7
 8
 9
10
11
12
13
14
15
@dataclass(frozen=True, slots=True)
class Grain:
    """Declare what one observation represents."""

    observation: str

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not self.observation.strip():
            raise ValueError("Grain observation must not be empty.")

__post_init__

__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/grain.py
12
13
14
15
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not self.observation.strip():
        raise ValueError("Grain observation must not be empty.")

LearningMode

Bases: StrEnum

Declare whether learning uses a target.

Source code in src/composable_data_core/learning_mode.py
 6
 7
 8
 9
10
class LearningMode(StrEnum):
    """Declare whether learning uses a target."""

    SUPERVISED = "supervised"
    UNSUPERVISED = "unsupervised"

ModelPlan dataclass

Declare one estimator choice and why it was chosen.

Source code in src/composable_data_core/model_plan.py
11
12
13
14
15
16
17
18
19
20
21
22
23
@dataclass(frozen=True, slots=True)
class ModelPlan:
    """Declare one estimator choice and why it was chosen."""

    estimator: str
    role: ModelRole
    rationale: Rationale
    parameters: Mapping[str, Any] = field(default_factory=dict)

    def __post_init__(self) -> None:
        """Validate the model plan."""
        if not self.estimator.strip():
            raise ValueError("Estimator name must not be empty.")

__post_init__

__post_init__() -> None

Validate the model plan.

Source code in src/composable_data_core/model_plan.py
20
21
22
23
def __post_init__(self) -> None:
    """Validate the model plan."""
    if not self.estimator.strip():
        raise ValueError("Estimator name must not be empty.")

ModelRole

Bases: StrEnum

Role played by a model in an experiment.

Source code in src/composable_data_core/model_role.py
 6
 7
 8
 9
10
class ModelRole(StrEnum):
    """Role played by a model in an experiment."""

    BASELINE = "baseline"
    CANDIDATE = "candidate"

ProblemType

Bases: StrEnum

Supported supervised prediction problem types.

Source code in src/composable_data_core/problem_type.py
 6
 7
 8
 9
10
class ProblemType(StrEnum):
    """Supported supervised prediction problem types."""

    CLASSIFICATION = "classification"
    REGRESSION = "regression"

RationaleTemplate

Bases: Protocol

Protocol for structured or canonical rationale objects.

Source code in src/composable_data_core/rationale_template.py
 6
 7
 8
 9
10
11
@runtime_checkable
class RationaleTemplate(Protocol):
    """Protocol for structured or canonical rationale objects."""

    def render(self) -> str:
        """Return a human-readable explanation."""

render

render() -> str

Return a human-readable explanation.

Source code in src/composable_data_core/rationale_template.py
10
11
def render(self) -> str:
    """Return a human-readable explanation."""

RationaleText dataclass

Structured wrapper for free-form rationale text.

Source code in src/composable_data_core/rationale_text.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@dataclass(frozen=True, slots=True)
class RationaleText:
    """Structured wrapper for free-form rationale text."""

    text: str

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not self.text.strip():
            raise ValueError("Rationale text must not be empty.")

    def render(self) -> str:
        """Return a human-readable explanation."""
        return self.text

__post_init__

__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/rationale_text.py
16
17
18
19
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not self.text.strip():
        raise ValueError("Rationale text must not be empty.")

render

render() -> str

Return a human-readable explanation.

Source code in src/composable_data_core/rationale_text.py
21
22
23
def render(self) -> str:
    """Return a human-readable explanation."""
    return self.text

Resolution dataclass

Declare what to do about a data problem and why.

Source code in src/composable_data_core/resolution.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@dataclass(frozen=True, slots=True)
class Resolution:
    """Declare what to do about a data problem and why."""

    problem: str
    action: ResolutionAction
    rationale: Rationale
    field: str | None = None
    original_value: Any | None = None
    resolved_value: Any | None = None

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not self.problem.strip():
            raise ValueError("Problem description must not be empty.")
        if self.action is ResolutionAction.RECODE and self.resolved_value is None:
            raise ValueError("RECODE resolutions require resolved_value.")

__post_init__

__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/resolution.py
21
22
23
24
25
26
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not self.problem.strip():
        raise ValueError("Problem description must not be empty.")
    if self.action is ResolutionAction.RECODE and self.resolved_value is None:
        raise ValueError("RECODE resolutions require resolved_value.")

ResolutionAction

Bases: StrEnum

Common analyst responses to identified data problems.

Source code in src/composable_data_core/resolution_action.py
 6
 7
 8
 9
10
11
12
class ResolutionAction(StrEnum):
    """Common analyst responses to identified data problems."""

    DROP = "drop"
    RECODE = "recode"
    IMPUTE = "impute"
    FLAG = "flag"

SplitMethod

Bases: StrEnum

Common train/test partition strategies.

Source code in src/composable_data_core/split_method.py
 6
 7
 8
 9
10
11
12
class SplitMethod(StrEnum):
    """Common train/test partition strategies."""

    RANDOM = "random"
    STRATIFIED = "stratified"
    GROUPED = "grouped"
    TIME_ORDERED = "time_ordered"

SplitPlan dataclass

Declare how training and test observations should be separated.

Source code in src/composable_data_core/split_plan.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@dataclass(frozen=True, slots=True)
class SplitPlan:
    """Declare how training and test observations should be separated."""

    method: SplitMethod
    test_size: float
    rationale: Rationale
    seed: int | None = None
    group_field: str | None = None
    time_field: str | None = None

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not 0.0 < self.test_size < 1.0:
            raise ValueError("test_size must be between 0 and 1.")
        if self.method is SplitMethod.GROUPED and not self.group_field:
            raise ValueError("Grouped splits require group_field.")
        if self.method is SplitMethod.TIME_ORDERED and not self.time_field:
            raise ValueError("Time-ordered splits require time_field.")

__post_init__

__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/split_plan.py
20
21
22
23
24
25
26
27
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not 0.0 < self.test_size < 1.0:
        raise ValueError("test_size must be between 0 and 1.")
    if self.method is SplitMethod.GROUPED and not self.group_field:
        raise ValueError("Grouped splits require group_field.")
    if self.method is SplitMethod.TIME_ORDERED and not self.time_field:
        raise ValueError("Time-ordered splits require time_field.")

evaluation

Recorded experiment evaluation evidence.

Evaluation dataclass

Record metric results computed elsewhere.

Source code in src/composable_data_core/evaluation.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
@dataclass(frozen=True, slots=True)
class Evaluation:
    """Record metric results computed elsewhere."""

    model_id: str
    metrics: Mapping[str, float]

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not self.model_id.strip():
            raise ValueError("model_id must not be empty.")
        if not self.metrics:
            raise ValueError("Evaluation must contain at least one metric.")
        object.__setattr__(self, "metrics", MappingProxyType(dict(self.metrics)))
__post_init__
__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/evaluation.py
15
16
17
18
19
20
21
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not self.model_id.strip():
        raise ValueError("model_id must not be empty.")
    if not self.metrics:
        raise ValueError("Evaluation must contain at least one metric.")
    object.__setattr__(self, "metrics", MappingProxyType(dict(self.metrics)))

experiment_assessment

Experiment assessment declaration.

ExperimentAssessment dataclass

Record the conclusion drawn from comparable experiment evidence.

Source code in src/composable_data_core/experiment_assessment.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@dataclass(frozen=True, slots=True)
class ExperimentAssessment:
    """Record the conclusion drawn from comparable experiment evidence."""

    comparison: str
    conclusion: str
    rationale: Rationale
    winner_model_id: str | None = None
    baseline_beaten: bool | None = None

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not self.comparison.strip():
            raise ValueError("Comparison description must not be empty.")
        if not self.conclusion.strip():
            raise ValueError("Conclusion must not be empty.")
__post_init__
__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/experiment_assessment.py
18
19
20
21
22
23
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not self.comparison.strip():
        raise ValueError("Comparison description must not be empty.")
    if not self.conclusion.strip():
        raise ValueError("Conclusion must not be empty.")

experiment_spec

Experiment specification declaration.

ExperimentSpec dataclass

Declare a complete analytical experiment before execution.

Source code in src/composable_data_core/experiment_spec.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
@dataclass(frozen=True, slots=True)
class ExperimentSpec[DatasetRefT]:
    """Declare a complete analytical experiment before execution."""

    dataset: DatasetRefT

    grain: Grain
    learning_mode: LearningMode
    problem_type: ProblemType

    target: str
    selected_features: tuple[str, ...]
    feature_rationale: Rationale

    resolution: Resolution
    split: SplitPlan

    baseline_id: str
    baseline: ModelPlan

    candidate_id: str
    candidate: ModelPlan

    def __post_init__(self) -> None:
        """Validate the experiment specification."""
        if not self.target.strip():
            raise ValueError("Target must not be empty.")

        if not self.selected_features:
            raise ValueError("Selected features must not be empty.")

        if self.target in self.selected_features:
            raise ValueError("Target must not also appear in selected features.")

        if not self.baseline_id.strip():
            raise ValueError("Baseline ID must not be empty.")

        if not self.candidate_id.strip():
            raise ValueError("Candidate ID must not be empty.")

        if self.baseline_id == self.candidate_id:
            raise ValueError("Baseline and candidate IDs must be different.")
__post_init__
__post_init__() -> None

Validate the experiment specification.

Source code in src/composable_data_core/experiment_spec.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def __post_init__(self) -> None:
    """Validate the experiment specification."""
    if not self.target.strip():
        raise ValueError("Target must not be empty.")

    if not self.selected_features:
        raise ValueError("Selected features must not be empty.")

    if self.target in self.selected_features:
        raise ValueError("Target must not also appear in selected features.")

    if not self.baseline_id.strip():
        raise ValueError("Baseline ID must not be empty.")

    if not self.candidate_id.strip():
        raise ValueError("Candidate ID must not be empty.")

    if self.baseline_id == self.candidate_id:
        raise ValueError("Baseline and candidate IDs must be different.")

grain

Observation grain declaration.

Grain dataclass

Declare what one observation represents.

Source code in src/composable_data_core/grain.py
 6
 7
 8
 9
10
11
12
13
14
15
@dataclass(frozen=True, slots=True)
class Grain:
    """Declare what one observation represents."""

    observation: str

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not self.observation.strip():
            raise ValueError("Grain observation must not be empty.")
__post_init__
__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/grain.py
12
13
14
15
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not self.observation.strip():
        raise ValueError("Grain observation must not be empty.")

learning_mode

Machine-learning learning mode.

LearningMode

Bases: StrEnum

Declare whether learning uses a target.

Source code in src/composable_data_core/learning_mode.py
 6
 7
 8
 9
10
class LearningMode(StrEnum):
    """Declare whether learning uses a target."""

    SUPERVISED = "supervised"
    UNSUPERVISED = "unsupervised"

model_plan

Model plan for a machine learning estimator.

ModelPlan dataclass

Declare one estimator choice and why it was chosen.

Source code in src/composable_data_core/model_plan.py
11
12
13
14
15
16
17
18
19
20
21
22
23
@dataclass(frozen=True, slots=True)
class ModelPlan:
    """Declare one estimator choice and why it was chosen."""

    estimator: str
    role: ModelRole
    rationale: Rationale
    parameters: Mapping[str, Any] = field(default_factory=dict)

    def __post_init__(self) -> None:
        """Validate the model plan."""
        if not self.estimator.strip():
            raise ValueError("Estimator name must not be empty.")
__post_init__
__post_init__() -> None

Validate the model plan.

Source code in src/composable_data_core/model_plan.py
20
21
22
23
def __post_init__(self) -> None:
    """Validate the model plan."""
    if not self.estimator.strip():
        raise ValueError("Estimator name must not be empty.")

model_role

Model role declaration.

ModelRole

Bases: StrEnum

Role played by a model in an experiment.

Source code in src/composable_data_core/model_role.py
 6
 7
 8
 9
10
class ModelRole(StrEnum):
    """Role played by a model in an experiment."""

    BASELINE = "baseline"
    CANDIDATE = "candidate"

problem_type

Machine-learning problem type.

ProblemType

Bases: StrEnum

Supported supervised prediction problem types.

Source code in src/composable_data_core/problem_type.py
 6
 7
 8
 9
10
class ProblemType(StrEnum):
    """Supported supervised prediction problem types."""

    CLASSIFICATION = "classification"
    REGRESSION = "regression"

rationale

Rationale type.

rationale_template

Shared rationale types.

RationaleTemplate

Bases: Protocol

Protocol for structured or canonical rationale objects.

Source code in src/composable_data_core/rationale_template.py
 6
 7
 8
 9
10
11
@runtime_checkable
class RationaleTemplate(Protocol):
    """Protocol for structured or canonical rationale objects."""

    def render(self) -> str:
        """Return a human-readable explanation."""
render
render() -> str

Return a human-readable explanation.

Source code in src/composable_data_core/rationale_template.py
10
11
def render(self) -> str:
    """Return a human-readable explanation."""

rationale_text

Rationale text type.

RationaleText dataclass

Structured wrapper for free-form rationale text.

Source code in src/composable_data_core/rationale_text.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@dataclass(frozen=True, slots=True)
class RationaleText:
    """Structured wrapper for free-form rationale text."""

    text: str

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not self.text.strip():
            raise ValueError("Rationale text must not be empty.")

    def render(self) -> str:
        """Return a human-readable explanation."""
        return self.text
__post_init__
__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/rationale_text.py
16
17
18
19
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not self.text.strip():
        raise ValueError("Rationale text must not be empty.")
render
render() -> str

Return a human-readable explanation.

Source code in src/composable_data_core/rationale_text.py
21
22
23
def render(self) -> str:
    """Return a human-readable explanation."""
    return self.text

resolution

Data-problem resolution declaration.

Resolution dataclass

Declare what to do about a data problem and why.

Source code in src/composable_data_core/resolution.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@dataclass(frozen=True, slots=True)
class Resolution:
    """Declare what to do about a data problem and why."""

    problem: str
    action: ResolutionAction
    rationale: Rationale
    field: str | None = None
    original_value: Any | None = None
    resolved_value: Any | None = None

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not self.problem.strip():
            raise ValueError("Problem description must not be empty.")
        if self.action is ResolutionAction.RECODE and self.resolved_value is None:
            raise ValueError("RECODE resolutions require resolved_value.")
__post_init__
__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/resolution.py
21
22
23
24
25
26
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not self.problem.strip():
        raise ValueError("Problem description must not be empty.")
    if self.action is ResolutionAction.RECODE and self.resolved_value is None:
        raise ValueError("RECODE resolutions require resolved_value.")

resolution_action

Data-problem resolution action.

ResolutionAction

Bases: StrEnum

Common analyst responses to identified data problems.

Source code in src/composable_data_core/resolution_action.py
 6
 7
 8
 9
10
11
12
class ResolutionAction(StrEnum):
    """Common analyst responses to identified data problems."""

    DROP = "drop"
    RECODE = "recode"
    IMPUTE = "impute"
    FLAG = "flag"

split_method

Train/test split method.

SplitMethod

Bases: StrEnum

Common train/test partition strategies.

Source code in src/composable_data_core/split_method.py
 6
 7
 8
 9
10
11
12
class SplitMethod(StrEnum):
    """Common train/test partition strategies."""

    RANDOM = "random"
    STRATIFIED = "stratified"
    GROUPED = "grouped"
    TIME_ORDERED = "time_ordered"

split_plan

Train/test split plan declaration.

SplitPlan dataclass

Declare how training and test observations should be separated.

Source code in src/composable_data_core/split_plan.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@dataclass(frozen=True, slots=True)
class SplitPlan:
    """Declare how training and test observations should be separated."""

    method: SplitMethod
    test_size: float
    rationale: Rationale
    seed: int | None = None
    group_field: str | None = None
    time_field: str | None = None

    def __post_init__(self) -> None:
        """After initialization validation on the dataclass fields."""
        if not 0.0 < self.test_size < 1.0:
            raise ValueError("test_size must be between 0 and 1.")
        if self.method is SplitMethod.GROUPED and not self.group_field:
            raise ValueError("Grouped splits require group_field.")
        if self.method is SplitMethod.TIME_ORDERED and not self.time_field:
            raise ValueError("Time-ordered splits require time_field.")
__post_init__
__post_init__() -> None

After initialization validation on the dataclass fields.

Source code in src/composable_data_core/split_plan.py
20
21
22
23
24
25
26
27
def __post_init__(self) -> None:
    """After initialization validation on the dataclass fields."""
    if not 0.0 < self.test_size < 1.0:
        raise ValueError("test_size must be between 0 and 1.")
    if self.method is SplitMethod.GROUPED and not self.group_field:
        raise ValueError("Grouped splits require group_field.")
    if self.method is SplitMethod.TIME_ORDERED and not self.time_field:
        raise ValueError("Time-ordered splits require time_field.")