Featuresmith Icon
Featuresmith
  • Docs
  • SDK
  • CLI
  • Examples
  • Roadmap
v0.4.0
Documentation

Getting Started

  • Introduction
  • Installation
  • Quick Start
  • Tutorial Notebooks
  • Benchmarks
  • Development Setup
  • Contributing

Core Concepts

  • Architecture Overview
  • Dataset Layer
  • Connectors
  • Profiling Engine
  • Rule Engine
  • Dataset Review Engine
  • ML Readiness Score
  • Target Leakage Detection
  • Dataset Diff Engine
  • Target Column Concept
  • Mental Model & Workflow
  • Interpreting Findings
  • Workflow Cheat Sheet
  • Beginner Glossary

Python SDK

  • load()
  • profile()
  • analyze()
  • review()
  • diff()
  • score()
  • plan()
  • Dataset
  • Data Models
  • Profile Models
  • Rule & Finding Models
  • Review Models
  • Score Models
  • Leakage Models
  • Diff Models
  • Exceptions
  • Plugins

CLI Reference

  • analyze
  • review
  • diff
  • score
  • plan
  • Configuration

Guides

  • CI/CD Integration
  • Custom Rules
  • Writing Plugins

Resources

  • Release Notes
  • FAQ
  • Troubleshooting
DocsGuide

Getting Started

  • Introduction
  • Installation
  • Quick Start
  • Tutorial Notebooks
  • Benchmarks
  • Development Setup
  • Contributing

Core Concepts

  • Architecture Overview
  • Dataset Layer
  • Connectors
  • Profiling Engine
  • Rule Engine
  • Dataset Review Engine
  • ML Readiness Score
  • Target Leakage Detection
  • Dataset Diff Engine
  • Target Column Concept
  • Mental Model & Workflow
  • Interpreting Findings
  • Workflow Cheat Sheet
  • Beginner Glossary

Python SDK

  • load()
  • profile()
  • analyze()
  • review()
  • diff()
  • score()
  • plan()
  • Dataset
  • Data Models
  • Profile Models
  • Rule & Finding Models
  • Review Models
  • Score Models
  • Leakage Models
  • Diff Models
  • Exceptions
  • Plugins

CLI Reference

  • analyze
  • review
  • diff
  • score
  • plan
  • Configuration

Guides

  • CI/CD Integration
  • Custom Rules
  • Writing Plugins

Resources

  • Release Notes
  • FAQ
  • Troubleshooting
HomeDocsDiff Models

Python SDK

Diff Models

SDK Reference: dataset diff result objects

fs.diff() profiles two snapshots and compares them, returning one frozen, serializable DatasetDiffResult — the equivalent of a git diff for structured datasets. All models below live in featuresmith.diff.schema.

DatasetDiffResult

python
1@dataclass(frozen=True, slots=True)
2class DatasetDiffResult:
3 version: str # "0.2.0"
4 schema: SchemaDiff
5 structure: StructureDiff
6 missing_values: tuple[MissingValueDiff, ...]
7 duplicates: DuplicateDiff
8 constant_columns: ConstantColumnDiff
9 cardinality: tuple[CardinalityDiff, ...]
10 statistics: tuple[StatisticDiff, ...]
11 distributions: tuple[DistributionDiff, ...]
12 leakage: LeakageDiff | None # None when no target column is given
13 summary: DatasetDiffSummary
14 overall_summary: str
15
16 def to_dict(self) -> dict[str, Any]: ...

DiffConfig

Tunable thresholds for the diff engine:

python
1@dataclass(frozen=True, slots=True)
2class DiffConfig:
3 distribution_shift_threshold: float = 0.10
4 missing_change_threshold: float = 1.0
5 duplicate_change_threshold: float = 1.0
6 numeric_tolerance: float = 1e-9

Schema-Level Deltas

python
1@dataclass(frozen=True, slots=True)
2class ColumnRename:
3 previous_name: str
4 name: str
5
6
7@dataclass(frozen=True, slots=True)
8class ColumnTypeChange:
9 column: str
10 previous_dtype: str
11 dtype: str
12 previous_logical_type: str
13 logical_type: str
14
15
16@dataclass(frozen=True, slots=True)
17class SchemaDiff:
18 added_columns: tuple[str, ...] = ()
19 removed_columns: tuple[str, ...] = ()
20 renamed_columns: tuple[ColumnRename, ...] = ()
21 type_changes: tuple[ColumnTypeChange, ...] = ()
22
23 @property
24 def changed(self) -> bool: ...

added_columns and removed_columns are plain column names.

StructureDiff

python
1@dataclass(frozen=True, slots=True)
2class StructureDiff:
3 previous_row_count: int
4 row_count: int
5 previous_column_count: int
6 column_count: int
7
8 @property
9 def rows_added(self) -> int: ... # never negative
10
11 @property
12 def rows_removed(self) -> int: ...
13
14 @property
15 def columns_added(self) -> int: ...
16
17 @property
18 def columns_removed(self) -> int: ...

Quality Deltas

python
1@dataclass(frozen=True, slots=True)
2class MissingValueDiff:
3 column: str
4 previous_missing_count: int
5 missing_count: int
6 previous_missing_percentage: float
7 missing_percentage: float
8
9 @property
10 def delta_count(self) -> int: ...
11 @property
12 def delta_percentage(self) -> float: ...
13 # status: "new" | "resolved" | "regressed" | "improved" | "unchanged"
14 @property
15 def status(self) -> str: ...
16
17
18@dataclass(frozen=True, slots=True)
19class DuplicateDiff:
20 previous_duplicate_count: int
21 duplicate_count: int
22 previous_duplicate_percentage: float
23 duplicate_percentage: float
24
25 @property
26 def delta_percentage(self) -> float: ...
27 # status: "regressed" | "improved" | "unchanged"
28 @property
29 def status(self) -> str: ...
30
31
32@dataclass(frozen=True, slots=True)
33class ConstantColumnDiff:
34 newly_constant: tuple[str, ...] = ()
35 no_longer_constant: tuple[str, ...] = ()
36
37 @property
38 def changed(self) -> bool: ...

MissingValueDiff.status reports "new" when missingness was introduced, "resolved" when it disappeared, "regressed"/"improved" when it increased/decreased, and "unchanged" otherwise.

Numeric Deltas

python
1@dataclass(frozen=True, slots=True)
2class CardinalityDiff:
3 column: str
4 previous_cardinality: int
5 cardinality: int
6
7 @property
8 def delta(self) -> int: ...
9
10
11@dataclass(frozen=True, slots=True)
12class StatisticDiff:
13 column: str
14 statistic: str # "mean" | "median" | "std_dev" | "minimum" | "maximum"
15 previous: float | None
16 current: float | None
17 delta: float | None
18 relative_delta: float | None
19
20
21@dataclass(frozen=True, slots=True)
22class DistributionDiff:
23 column: str
24 previous_mean: float | None
25 mean: float | None
26 mean_relative_shift: float | None
27 significant: bool

Only statistics that actually changed are emitted, and only distribution shifts that exceed the configured threshold are flagged.

Leakage Deltas

python
1@dataclass(frozen=True, slots=True)
2class LeakageColumnDiff:
3 column: str
4 previous_severity: str | None
5 severity: str | None
6 status: str # "new" | "removed" | "escalated" | "de_escalated" | "unchanged"
7
8 @property
9 def changed(self) -> bool: ...
10
11
12@dataclass(frozen=True, slots=True)
13class LeakageDiff:
14 columns: tuple[LeakageColumnDiff, ...] = ()
15
16 @property
17 def new_findings(self) -> tuple[LeakageColumnDiff, ...]: ...
18 @property
19 def removed_findings(self) -> tuple[LeakageColumnDiff, ...]: ...
20 @property
21 def escalated(self) -> tuple[LeakageColumnDiff, ...]: ...
22 @property
23 def de_escalated(self) -> tuple[LeakageColumnDiff, ...]: ...
24 @property
25 def changed(self) -> bool: ...

The leakage comparison is only produced when a target column is provided to fs.diff().

DatasetDiffSummary

python
1@dataclass(frozen=True, slots=True)
2class DatasetDiffSummary:
3 rows_added: int
4 rows_removed: int
5 columns_added: int
6 columns_removed: int
7 columns_renamed: int
8 type_changes: int
9 schema_changed: bool
10 missing_values_increased: int
11 missing_values_decreased: int
12 duplicate_rows_increased: bool
13 duplicate_rows_decreased: bool
14 newly_constant_columns: int
15 no_longer_constant_columns: int
16 leakage_new: int
17 leakage_removed: int
18 leakage_escalated: int
19 leakage_de_escalated: int
20 overall_health: str # "regressed" | "improved" | "unchanged"
21 recommendation: str

Example

python
1import featuresmith as fs
2
3result = fs.diff("v1.csv", "v2.csv", target_column="churn")
4
5print(result.overall_summary)
6print(f"Health: {result.summary.overall_health}")
7for diff in result.missing_values:
8 print(f" {diff.column}: {diff.status} ({diff.delta_percentage:+.2f}pp)")

Explore

  • Quick Start
  • Python SDK
  • CLI Reference
  • Examples
Featuresmith Icon
Featuresmith

Open-source data profiling and validation for Python engineers.

Documentation

  • Introduction
  • Quick Start
  • Python SDK
  • CLI Reference

Community

  • GitHub
  • Discussions
  • Issues
  • Contributing

Project

  • Roadmap
  • Release status
  • Benchmarks
  • Changelog
  • Examples

Legal

  • Apache 2.0 License
  • Code of Conduct
  • Security

© 2026 Featuresmith Contributors. Released under the Apache 2.0 License.

Built by Aditya Gangwani in the open.