-
-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference
Import the public surface as:
import cleanframe as cfFull export list: cf.__all__. Below are the calls most applications use.
Profile, plan, and clean.
| Parameter | Type | Default | Notes |
|---|---|---|---|
data |
DataFrame | path | required | CSV/TSV/Excel/Parquet/JSON via read_frame
|
target_schema / schema
|
Schema | path | dict | None |
Drives mapping + validations |
llm |
None | "provider/model" | client |
None |
Rules-only when omitted |
mode |
"review" | "auto" | "strict"
|
"review" |
|
options |
dict | {} |
Detector knobs + max_diff_changes
|
max_tokens_budget |
int | None | None |
Hard LLM token cap |
llm_exposure |
"metadata" | "sample" | "none"
|
"metadata" |
What the model may see |
sheet |
str | int | None
|
None |
Excel sheet name / 0-based index (file input) |
columns |
list[str] | None
|
None |
usecols filter — keeps file order, not a reorder |
nrows / skiprows
|
int | None
|
None |
Row slice (file input); diff row_id is slice-relative |
correct_format |
bool |
True |
CSV encoding + delimiter auto-detect, pinned to read:; ambiguous delimiter raises (CLI --no-correct) |
sheet / columns / nrows / skiprows are also accepted by report, apply_recipe, infer_schema; correct_format by report. On a DataFrame input columns projects while sheet / nrows / skiprows raise (file-only).
result = cf.clean(df, target_schema="schema.yaml", mode="auto")
result.dataframe
result.recipe
result.diff
result.quarantine
result.issues
result.quality
result.log
result.code # CodeArtifact — standalone pandasUseful options keys:
| Key | Effect |
|---|---|
max_diff_changes |
Cap stored cell diffs (None = unlimited; default 100_000) |
dayfirst |
Date ambiguity preference for the dates detector |
phone_country_code |
Default country code for phone normalisation |
category_map |
Seed alias map {column: {variant: canonical}}
|
Profile + detect only; returns an HTML report object.
rep = cf.report("data.csv")
rep.save("report.html")
html = rep.htmlReplay without re-planning.
| Parameter | Default | Notes |
|---|---|---|
check_drift |
True |
Compare fingerprint |
on_drift |
"error" |
"error" | "warn" | "ignore"
|
mode |
"review" |
strict always raises on drift |
Mechanical drift patches (repoint renamed columns, extend date formats).
Draft schema from observed types / categories.
Low-level deterministic replay (used by clean / apply_recipe).
Clean every sheet of an .xlsx independently — one Recipe + diff per sheet.
| Call | Returns | Notes |
|---|---|---|
cf.clean_workbook(data, *, sheets=None, target_schema=None, schema=None, llm=None, mode="review", options=None) |
WorkbookResult |
sheets= limits which tabs |
cf.apply_workbook(data, recipe, *, mode="review", check_drift=True, on_drift="error") |
WorkbookResult |
Replay a WorkbookRecipe across sheets |
cf.read_workbook(path, sheets=None) |
dict[str, DataFrame] |
|
cf.load_recipe(path) |
Recipe | WorkbookRecipe
|
Auto-detects a sheets: block |
wb = cf.clean_workbook("book.xlsx", target_schema="schema.yaml")
wb.sheets # dict name -> CleanResult
wb.untouched # sheet names left unchanged
wb.frames # dict name -> DataFrame (cleaned or untouched)
wb.recipe # WorkbookRecipe
wb.summary()
wb.save_recipe("book.recipe.yaml")
wb.save_data("out.xlsx") # every sheet to one .xlsx; refuses to overwrite the source (overwrite=True to force)WorkbookRecipe is one reviewable YAML — version: 2 with a top-level sheets: mapping (sheet name -> a normal recipe); exposes .sheets, .save(path), .load(path). A per-sheet recipe never carries its own read.sheet — the dict key is the sheet.
A multi-sheet workbook with no sheet selected raises CleanFrameError listing the sheet names — read_frame / clean / report / apply / infer_schema never silently read sheet 1. The CLI auto-routes a multi-sheet .xlsx to workbook mode.
Replay a row-independent recipe over a CSV in chunks — peak memory is bounded by chunksize, not file size.
summary = cf.stream_apply(recipe, "big.csv", "clean.csv", chunksize=100_000)
summary.rows_in, summary.rows_out, summary.changed_cells
summary.rows_dropped, summary.rows_quarantined, summary.chunks
print(summary.render())| Parameter | Default | Notes |
|---|---|---|
chunksize |
100_000 |
Peak memory ≈ one chunk |
mode |
"review" |
|
check_drift / on_drift
|
True / "error"
|
Drift checked on a bounded head sample |
quarantine_path |
None |
Write dropped / quarantined rows |
cf.check_streamable(recipe) is the pre-flight. GLOBAL ops are refused with a named CleanFrameError: dedup; fill_na with mean/median/mode/ffill/bfill; cast to category/datetime/date; parse_date without explicit formats; the unique validator; and any unknown custom op (default-DENY).
CLI: cleanframe apply FILE --recipe R --chunksize N [--out O] streams; global-op recipes print a clear refusal.
cf.read_frame("data.parquet")
cf.write_frame(df, "out.csv") # formula-safe by default
cf.write_frame(df, "out.csv", sanitize_csv=False)@cf.detector("iban", priority=45)
def detect_iban(series, ctx): ...
@cf.register_op("my_op", scope="column", ...)
def my_op(series, **params): ...
@cf.validator("valid_iban")
def _(series): ...See Detectors & ops and CONTRIBUTING.md.
| Exception | When |
|---|---|
CleanFrameError |
Base / IO |
RecipeError |
Invalid recipe / check |
OpError |
Op params / execution |
ExecutionError |
Strict missing column, rename clash |
ValidationFailure |
on_fail=error / strict |
DriftError |
Schema drift on apply |
SchemaError |
Bad schema YAML |
LLMError / BudgetExceeded
|
LLM path (may fall back to rules) |