Skip to content

Commit 3d7a786

Browse files
Merge pull request #1 from FreshCode-Org/feature/repair-plan-p0
Add repair plan artifacts
2 parents 2d8ad46 + ca03262 commit 3d7a786

6 files changed

Lines changed: 571 additions & 6 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ level, and confidence score — no silent mutations.
177177
| name | purpose |
178178
|---|---|
179179
| `fd.clean(df, *, return_report=False, config=None, **options)` | clean, optionally returning a `CleanReport` |
180+
| `fd.plan(df, *, mode="suggest", **options)` | build a serializable `RepairPlan` with row, column, and cell patches |
181+
| `fd.repair(df, *, mode="repair_safe", return_plan=False, **options)` | apply safe, reviewed, or aggressive repair modes |
180182
| `fd.profile(df, *, include_plan=False, **options)` | read-only inspection with actionable issues |
181183
| `fd.suggest_plan(df, **options)` | dry-run: primary + alternative models per column |
182184
| `fd.compare_plans(df, *, strategies=...)` | side-by-side models across strategies |
@@ -185,6 +187,7 @@ level, and confidence score — no silent mutations.
185187
| `fd.Cleaner(config=None, **options)` | reusable configured pipeline (`.clean()`, `.report_`) |
186188
| `fd.CleanConfig` | frozen dataclass holding every option |
187189
| `fd.CleanReport` / `fd.Action` | audit trail with rationale / risk / confidence |
190+
| `fd.RepairPlan` / `fd.RepairPatch` | reversible repair artifact and patch log |
188191

189192
```python
190193
# Tune the engine — explicit choices always override the defaults

docs/api-reference.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
22
title: API reference
33
description: >-
4-
Complete freshdata API reference — clean, profile, suggest_plan, compare_plans,
5-
compare_clean, explain_clean, the Cleaner pipeline, CleanConfig, and reports.
4+
Complete freshdata API reference — clean, plan, repair, profile, suggest_plan,
5+
compare_plans, compare_clean, explain_clean, Cleaner, CleanConfig, and reports.
66
keywords: freshdata api, fd.clean, CleanConfig, CleanReport, pandas cleaning api
77
---
88

@@ -15,6 +15,8 @@ top-level attribute of `freshdata` (e.g. `import freshdata as fd; fd.clean(...)`
1515

1616
::: freshdata.clean
1717

18+
::: freshdata.repair
19+
1820
::: freshdata.Cleaner
1921

2022
## Profiling & inspection
@@ -29,6 +31,8 @@ top-level attribute of `freshdata` (e.g. `import freshdata as fd; fd.clean(...)`
2931

3032
::: freshdata.suggest_plan
3133

34+
::: freshdata.plan
35+
3236
::: freshdata.compare_plans
3337

3438
::: freshdata.compare_clean
@@ -47,6 +51,12 @@ top-level attribute of `freshdata` (e.g. `import freshdata as fd; fd.clean(...)`
4751

4852
::: freshdata.ColumnPlan
4953

54+
::: freshdata.RepairPlan
55+
56+
::: freshdata.RepairPatch
57+
58+
::: freshdata.ReviewItem
59+
5060
::: freshdata.Profile
5161

5262
::: freshdata.ColumnProfile

src/freshdata/__init__.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,19 @@
2222
sample-based pre-screening so type inference stays cheap on large frames.
2323
"""
2424

25-
from .api import clean, infer_roles, profile, suggest_plan
25+
from .api import clean, infer_roles, plan, profile, repair, suggest_plan
2626
from .cleaner import Cleaner
2727
from .config import CleanConfig
2828
from .explain import ExplainReport, explain_clean
29-
from .plan import CleanPlan, ColumnPlan, compare_clean, compare_plans
29+
from .plan import (
30+
CleanPlan,
31+
ColumnPlan,
32+
RepairPatch,
33+
RepairPlan,
34+
ReviewItem,
35+
compare_clean,
36+
compare_plans,
37+
)
3038
from .profile import ColumnProfile, Profile
3139
from .report import Action, CleanReport
3240

@@ -42,13 +50,18 @@
4250
"ExplainReport",
4351
"ColumnProfile",
4452
"Profile",
53+
"RepairPatch",
54+
"RepairPlan",
55+
"ReviewItem",
4556
"__version__",
4657
"clean",
4758
"compare_clean",
4859
"compare_plans",
4960
"explain_clean",
5061
"infer_roles",
62+
"plan",
5163
"profile",
64+
"repair",
5265
"suggest_plan",
5366
]
5467

src/freshdata/api.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from .config import CleanConfig, merge_options
1212
from .engine.context import build_contexts
1313
from .engine.model_select import EngineMode, rank_missing_models
14-
from .plan import suggest_plan
14+
from .plan import RepairPlan, build_repair_plan, suggest_plan
1515
from .profile import Profile, build_profile
1616
from .report import CleanReport
1717

@@ -132,6 +132,46 @@ def clean(
132132
return from_pandas(result, df)
133133

134134

135+
def plan(
136+
df: pd.DataFrame,
137+
*,
138+
mode: str = "suggest",
139+
config: CleanConfig | None = None,
140+
**options: object,
141+
) -> RepairPlan:
142+
"""Build a previewable, serializable repair plan without changing *df*.
143+
144+
``mode="suggest"`` runs the configured cleaner and records the proposed
145+
row, column, and cell patches. ``mode="inspect"`` records only the source
146+
fingerprint and shape. ``mode="repair_safe"`` limits the plan to
147+
deterministic representation repairs by disabling statistical engine
148+
actions.
149+
"""
150+
return build_repair_plan(to_pandas(df), mode=mode, config=config, **options)
151+
152+
153+
def repair(
154+
df: pd.DataFrame,
155+
*,
156+
mode: str = "repair_safe",
157+
approved_patch_ids: set[str] | None = None,
158+
return_plan: bool = False,
159+
config: CleanConfig | None = None,
160+
**options: object,
161+
) -> pd.DataFrame | tuple[pd.DataFrame, RepairPlan]:
162+
"""Apply a repair mode and optionally return the repair plan.
163+
164+
``mode="repair_reviewed"`` applies only ``approved_patch_ids``. Other
165+
modes apply every patch proposed by the plan.
166+
"""
167+
repair_plan = build_repair_plan(to_pandas(df), mode=mode, config=config, **options)
168+
approved = set(approved_patch_ids or ()) if mode == "repair_reviewed" else None
169+
repaired = from_pandas(repair_plan.apply(approved), df)
170+
if return_plan:
171+
return repaired, repair_plan
172+
return repaired
173+
174+
135175
def _engine_mode(cfg: CleanConfig) -> EngineMode:
136176
mode = cfg.engine_mode or "balanced"
137177
return "balanced" if mode == "balanced" else "aggressive"

0 commit comments

Comments
 (0)