prepro-auto 1.0.0b1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prepro_auto-1.0.0b1/.env.example +58 -0
- prepro_auto-1.0.0b1/LICENSE +21 -0
- prepro_auto-1.0.0b1/MANIFEST.in +9 -0
- prepro_auto-1.0.0b1/PKG-INFO +270 -0
- prepro_auto-1.0.0b1/README.md +201 -0
- prepro_auto-1.0.0b1/app/__init__.py +0 -0
- prepro_auto-1.0.0b1/app/api/__init__.py +0 -0
- prepro_auto-1.0.0b1/app/api/router.py +16 -0
- prepro_auto-1.0.0b1/app/api/routes/__init__.py +0 -0
- prepro_auto-1.0.0b1/app/api/routes/datasets.py +463 -0
- prepro_auto-1.0.0b1/app/api/routes/decisions.py +302 -0
- prepro_auto-1.0.0b1/app/api/routes/execution.py +116 -0
- prepro_auto-1.0.0b1/app/api/routes/export.py +69 -0
- prepro_auto-1.0.0b1/app/api/routes/health.py +159 -0
- prepro_auto-1.0.0b1/app/api/routes/transform.py +338 -0
- prepro_auto-1.0.0b1/app/core/__init__.py +0 -0
- prepro_auto-1.0.0b1/app/core/config.py +129 -0
- prepro_auto-1.0.0b1/app/core/logging.py +47 -0
- prepro_auto-1.0.0b1/app/core/memory.py +143 -0
- prepro_auto-1.0.0b1/app/db/__init__.py +0 -0
- prepro_auto-1.0.0b1/app/db/session.py +73 -0
- prepro_auto-1.0.0b1/app/main.py +108 -0
- prepro_auto-1.0.0b1/app/models/__init__.py +16 -0
- prepro_auto-1.0.0b1/app/models/decision.py +78 -0
- prepro_auto-1.0.0b1/app/models/job.py +92 -0
- prepro_auto-1.0.0b1/app/models/snapshot.py +81 -0
- prepro_auto-1.0.0b1/app/notebook.py +208 -0
- prepro_auto-1.0.0b1/app/preprocessing/__init__.py +0 -0
- prepro_auto-1.0.0b1/app/preprocessing/abbreviations.py +200 -0
- prepro_auto-1.0.0b1/app/preprocessing/correlation.py +152 -0
- prepro_auto-1.0.0b1/app/preprocessing/encoding.py +127 -0
- prepro_auto-1.0.0b1/app/preprocessing/imputation.py +328 -0
- prepro_auto-1.0.0b1/app/preprocessing/missing_values.py +293 -0
- prepro_auto-1.0.0b1/app/preprocessing/outliers.py +216 -0
- prepro_auto-1.0.0b1/app/preprocessing/profiler.py +169 -0
- prepro_auto-1.0.0b1/app/preprocessing/scaling.py +175 -0
- prepro_auto-1.0.0b1/app/preprocessing/semantics.py +190 -0
- prepro_auto-1.0.0b1/app/preprocessing/transforms.py +520 -0
- prepro_auto-1.0.0b1/app/preprocessing/type_inference.py +223 -0
- prepro_auto-1.0.0b1/app/schemas/__init__.py +0 -0
- prepro_auto-1.0.0b1/app/schemas/decision.py +52 -0
- prepro_auto-1.0.0b1/app/schemas/execution.py +50 -0
- prepro_auto-1.0.0b1/app/schemas/job.py +77 -0
- prepro_auto-1.0.0b1/app/services/__init__.py +0 -0
- prepro_auto-1.0.0b1/app/services/dashboard_service.py +112 -0
- prepro_auto-1.0.0b1/app/services/dataset_inspector.py +78 -0
- prepro_auto-1.0.0b1/app/services/drift_service.py +181 -0
- prepro_auto-1.0.0b1/app/services/encoding_service.py +98 -0
- prepro_auto-1.0.0b1/app/services/execution_service.py +176 -0
- prepro_auto-1.0.0b1/app/services/export_service.py +311 -0
- prepro_auto-1.0.0b1/app/services/file_reader.py +163 -0
- prepro_auto-1.0.0b1/app/services/llm_client.py +292 -0
- prepro_auto-1.0.0b1/app/services/llm_transform_service.py +496 -0
- prepro_auto-1.0.0b1/app/services/missing_value_service.py +109 -0
- prepro_auto-1.0.0b1/app/services/outlier_service.py +166 -0
- prepro_auto-1.0.0b1/app/services/profiling_service.py +62 -0
- prepro_auto-1.0.0b1/app/services/scaling_service.py +186 -0
- prepro_auto-1.0.0b1/app/services/storage.py +129 -0
- prepro_auto-1.0.0b1/app/services/transform_service.py +111 -0
- prepro_auto-1.0.0b1/app/services/versioning_service.py +173 -0
- prepro_auto-1.0.0b1/app/services/visualization_service.py +171 -0
- prepro_auto-1.0.0b1/app/web/__init__.py +1 -0
- prepro_auto-1.0.0b1/app/web/review.html +270 -0
- prepro_auto-1.0.0b1/app/web/workbench.html +1675 -0
- prepro_auto-1.0.0b1/app/workers/__init__.py +0 -0
- prepro_auto-1.0.0b1/app/workers/celery_app.py +33 -0
- prepro_auto-1.0.0b1/app/workers/tasks.py +48 -0
- prepro_auto-1.0.0b1/prepro_auto/__init__.py +57 -0
- prepro_auto-1.0.0b1/prepro_auto/cli.py +38 -0
- prepro_auto-1.0.0b1/prepro_auto.egg-info/PKG-INFO +270 -0
- prepro_auto-1.0.0b1/prepro_auto.egg-info/SOURCES.txt +76 -0
- prepro_auto-1.0.0b1/prepro_auto.egg-info/dependency_links.txt +1 -0
- prepro_auto-1.0.0b1/prepro_auto.egg-info/entry_points.txt +2 -0
- prepro_auto-1.0.0b1/prepro_auto.egg-info/requires.txt +52 -0
- prepro_auto-1.0.0b1/prepro_auto.egg-info/top_level.txt +2 -0
- prepro_auto-1.0.0b1/pyproject.toml +98 -0
- prepro_auto-1.0.0b1/requirements.txt +45 -0
- prepro_auto-1.0.0b1/setup.cfg +4 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Copy this file to .env and adjust as needed.
|
|
2
|
+
# For local dev with no Docker, the defaults below work as-is.
|
|
3
|
+
|
|
4
|
+
APP_NAME=PrePro Auto
|
|
5
|
+
APP_ENV=local
|
|
6
|
+
DEBUG=true
|
|
7
|
+
|
|
8
|
+
# ── Database ──────────────────────────────────────────────
|
|
9
|
+
# Local (no Docker): SQLite file
|
|
10
|
+
DATABASE_URL=sqlite:///./prepro_auto.db
|
|
11
|
+
# Docker/Postgres example:
|
|
12
|
+
# DATABASE_URL=postgresql+psycopg2://prepro_auto:prepro_auto@db:5432/prepro_auto
|
|
13
|
+
|
|
14
|
+
# ── Redis ─────────────────────────────────────────────────
|
|
15
|
+
REDIS_URL=redis://localhost:6379/0
|
|
16
|
+
|
|
17
|
+
# ── Storage ───────────────────────────────────────────────
|
|
18
|
+
# Local (no Docker): filesystem
|
|
19
|
+
STORAGE_BACKEND=local
|
|
20
|
+
LOCAL_STORAGE_DIR=./storage
|
|
21
|
+
# MinIO/S3 example:
|
|
22
|
+
# STORAGE_BACKEND=s3
|
|
23
|
+
# S3_ENDPOINT_URL=http://localhost:9000
|
|
24
|
+
# S3_ACCESS_KEY=minioadmin
|
|
25
|
+
# S3_SECRET_KEY=minioadmin
|
|
26
|
+
# S3_BUCKET=prepro_auto
|
|
27
|
+
|
|
28
|
+
# ── Upload limits ─────────────────────────────────────────
|
|
29
|
+
MAX_UPLOAD_MB=2048
|
|
30
|
+
ALLOWED_EXTENSIONS=csv,parquet,xlsx,xls,json
|
|
31
|
+
|
|
32
|
+
# ── LLM (optional) ────────────────────────────────────────
|
|
33
|
+
# Leave LLM_PROVIDER empty to run fully offline (dictionary handles common names).
|
|
34
|
+
# Choose ONE provider, set LLM_PROVIDER to its name, then fill in that key.
|
|
35
|
+
# You can also configure this AT RUNTIME from the workbench's "AI settings"
|
|
36
|
+
# panel or, in a notebook, with prepro_auto.set_api_key("openai", "sk-...").
|
|
37
|
+
#
|
|
38
|
+
# OPTION 1 — Groq (free tier, fast, great for testing):
|
|
39
|
+
# pip install groq · https://console.groq.com · LLM_PROVIDER=groq
|
|
40
|
+
# OPTION 2 — OpenAI / GPT:
|
|
41
|
+
# pip install openai · https://platform.openai.com · LLM_PROVIDER=openai
|
|
42
|
+
# OPTION 3 — Anthropic Claude (production):
|
|
43
|
+
# pip install anthropic · https://console.anthropic.com · LLM_PROVIDER=anthropic
|
|
44
|
+
# OPTION 4 — Google Gemini:
|
|
45
|
+
# pip install google-generativeai · https://aistudio.google.com/app/apikey · LLM_PROVIDER=gemini
|
|
46
|
+
# OPTION 5 — Mistral:
|
|
47
|
+
# pip install mistralai · https://console.mistral.ai · LLM_PROVIDER=mistral
|
|
48
|
+
LLM_PROVIDER=
|
|
49
|
+
GROQ_API_KEY=
|
|
50
|
+
GROQ_MODEL=llama-3.3-70b-versatile
|
|
51
|
+
OPENAI_API_KEY=
|
|
52
|
+
OPENAI_MODEL=gpt-4o-mini
|
|
53
|
+
ANTHROPIC_API_KEY=
|
|
54
|
+
LLM_MODEL=claude-sonnet-4-20250514
|
|
55
|
+
GEMINI_API_KEY=
|
|
56
|
+
GEMINI_MODEL=gemini-1.5-flash
|
|
57
|
+
MISTRAL_API_KEY=
|
|
58
|
+
MISTRAL_MODEL=mistral-small-latest
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PrepIQ
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: prepro-auto
|
|
3
|
+
Version: 1.0.0b1
|
|
4
|
+
Summary: AI-assisted, human-in-the-loop tabular data preprocessing — profile, clean, transform, and export any dataset with a reproducible pipeline, from a notebook or the web.
|
|
5
|
+
Author: Shivanshu Pandey
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Chilliflex/prepro_auto
|
|
8
|
+
Project-URL: Documentation, https://github.com/Chilliflex/prepro_auto#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/Chilliflex/prepro_auto
|
|
10
|
+
Keywords: data-preprocessing,data-cleaning,machine-learning,pandas,data-quality,feature-engineering,etl,data-science
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: fastapi>=0.110
|
|
25
|
+
Requires-Dist: uvicorn[standard]>=0.29
|
|
26
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
27
|
+
Requires-Dist: pydantic>=2.6
|
|
28
|
+
Requires-Dist: pydantic-settings>=2.2
|
|
29
|
+
Requires-Dist: sqlalchemy>=2.0
|
|
30
|
+
Requires-Dist: pandas>=2.0
|
|
31
|
+
Requires-Dist: numpy>=1.24
|
|
32
|
+
Requires-Dist: scikit-learn>=1.3
|
|
33
|
+
Requires-Dist: scipy>=1.10
|
|
34
|
+
Requires-Dist: reportlab>=4.0
|
|
35
|
+
Requires-Dist: pyarrow>=14.0
|
|
36
|
+
Requires-Dist: openpyxl>=3.1
|
|
37
|
+
Requires-Dist: python-dotenv>=1.0
|
|
38
|
+
Requires-Dist: psutil>=5.9
|
|
39
|
+
Requires-Dist: nest-asyncio>=1.5
|
|
40
|
+
Provides-Extra: groq
|
|
41
|
+
Requires-Dist: groq>=0.11; extra == "groq"
|
|
42
|
+
Provides-Extra: openai
|
|
43
|
+
Requires-Dist: openai>=1.40; extra == "openai"
|
|
44
|
+
Provides-Extra: anthropic
|
|
45
|
+
Requires-Dist: anthropic>=0.40; extra == "anthropic"
|
|
46
|
+
Provides-Extra: gemini
|
|
47
|
+
Requires-Dist: google-generativeai>=0.7; extra == "gemini"
|
|
48
|
+
Provides-Extra: mistral
|
|
49
|
+
Requires-Dist: mistralai>=1.0; extra == "mistral"
|
|
50
|
+
Provides-Extra: ai
|
|
51
|
+
Requires-Dist: groq>=0.11; extra == "ai"
|
|
52
|
+
Requires-Dist: openai>=1.40; extra == "ai"
|
|
53
|
+
Requires-Dist: anthropic>=0.40; extra == "ai"
|
|
54
|
+
Requires-Dist: google-generativeai>=0.7; extra == "ai"
|
|
55
|
+
Requires-Dist: mistralai>=1.0; extra == "ai"
|
|
56
|
+
Provides-Extra: hosting
|
|
57
|
+
Requires-Dist: psycopg2-binary>=2.9; extra == "hosting"
|
|
58
|
+
Requires-Dist: boto3>=1.34; extra == "hosting"
|
|
59
|
+
Requires-Dist: alembic>=1.13; extra == "hosting"
|
|
60
|
+
Requires-Dist: celery>=5.3; extra == "hosting"
|
|
61
|
+
Requires-Dist: redis>=5.0; extra == "hosting"
|
|
62
|
+
Provides-Extra: dev
|
|
63
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
64
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
65
|
+
Requires-Dist: httpx>=0.27; extra == "dev"
|
|
66
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
67
|
+
Requires-Dist: twine>=5.0; extra == "dev"
|
|
68
|
+
Dynamic: license-file
|
|
69
|
+
|
|
70
|
+
# PrePro Auto
|
|
71
|
+
|
|
72
|
+
**AI-assisted tabular data preprocessing with human-in-the-loop control.**
|
|
73
|
+
|
|
74
|
+
Profile, clean, transform, and export any tabular dataset — from a Jupyter notebook or a local web UI — with every step undoable, auditable, and reproducible. The same engine drives both interfaces, so results are identical wherever you call it from.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install prepro-auto
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
> Author: [Shivanshu Pandey](https://github.com/Chilliflex) · Source: [github.com/Chilliflex/prepro_auto](https://github.com/Chilliflex/prepro_auto)
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Quickstart — Notebook (no upload)
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
import pandas as pd
|
|
88
|
+
import prepro_auto
|
|
89
|
+
|
|
90
|
+
df = pd.read_csv("your_data.csv")
|
|
91
|
+
session = prepro_auto.launch(df) # opens the local workbench, NO upload
|
|
92
|
+
# -> click the printed http://127.0.0.1:8721/workbench?job=... link
|
|
93
|
+
|
|
94
|
+
# clean visually in the browser, then back in the notebook:
|
|
95
|
+
cleaned = session.current() # the UI-edited DataFrame
|
|
96
|
+
session.update(cleaned) # push notebook edits back to the UI
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
That's the whole loop. Your DataFrame is loaded directly from the notebook's memory — no file upload, no context switch. `df` (your original) never changes; `session.current()` always returns the latest cleaned version.
|
|
100
|
+
|
|
101
|
+
## Quickstart — Web UI
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
prepro_auto # starts the workbench at http://127.0.0.1:8000
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Then open `http://127.0.0.1:8000/workbench` and upload a file.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## What it does
|
|
112
|
+
|
|
113
|
+
- **Profile** — per-column type inference, missing rates, 0–100 quality score
|
|
114
|
+
- **Clean (guided)** — missing values, outliers, scaling, correlation/leakage, encoding; each issue becomes a reviewable decision with a recommended action and alternatives
|
|
115
|
+
- **Transform (manual)** — 17 preset ops, sandboxed expressions, multi-column batches
|
|
116
|
+
- **AI assistant** — optional; describe a change in plain English; confirms intent and shows a real preview before applying
|
|
117
|
+
- **Visualize & dashboard** — histograms, bar, scatter charts, plus a before/after dashboard with KPI tiles and per-column comparison
|
|
118
|
+
- **Data drift** — compare two datasets to detect distribution shifts (PSI + KS)
|
|
119
|
+
- **Undo/redo** — every change is a version
|
|
120
|
+
- **Export** — clean data (CSV/Parquet), audit PDF, and a runnable Python pipeline script
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## What you get out of PrePro Auto
|
|
125
|
+
|
|
126
|
+
Five concrete outputs you can take away after a session. Each one is designed to plug straight into a real-world workflow:
|
|
127
|
+
|
|
128
|
+
| Output | What it is | Where to use it |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| **Cleaned DataFrame** | The in-memory DataFrame after all your cleaning + transforms, returned by `session.current()` in the notebook | Feed straight into `model.fit(X, y)` for scikit-learn, XGBoost, LightGBM, PyTorch, TensorFlow. No file I/O needed. |
|
|
131
|
+
| **Cleaned dataset file** | A CSV or Parquet file via `GET /datasets/{job_id}/export/data?format=csv` (or `format=parquet`) | Share with teammates, upload to a feature store, load into BI tools (Tableau, Power BI, Looker), commit to a versioned data repo, or feed into downstream ETL jobs. Parquet is smaller and faster for large datasets. |
|
|
132
|
+
| **Audit PDF** | A multi-page PDF via `GET /datasets/{job_id}/export/audit` listing every transformation with its parameters, before/after stats, and who approved it | Compliance trail for regulated industries (finance, healthcare, insurance); attach to a model-card or experiment-tracking entry; hand to a reviewer or data-governance team to prove the cleaning is reproducible and reasoned, not arbitrary. |
|
|
133
|
+
| **Runnable Python pipeline** | A standalone `.py` script via `GET /datasets/{job_id}/export/pipeline` that reproduces the exact cleaning with pandas + scikit-learn — no PrePro Auto dependency | Drop into a production training pipeline, an Airflow/Prefect/Dagster DAG, a CI job, or a coworker's machine. They run `python pipeline.py raw.csv clean.csv` and get the same result you produced visually. |
|
|
134
|
+
| **Drift report** | A per-column JSON verdict (PSI, KS test, severity bands) via `POST /drift/compare` between two datasets | Monitor a deployed model — compare last month's input distribution to this month's. Catch silent data shifts (a new product category, a sensor recalibration, a market regime change) before they degrade model performance. Plug into a monitoring dashboard or alert on `overall_verdict == "significant_drift"`. |
|
|
135
|
+
|
|
136
|
+
**Two common workflows:**
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
# Workflow 1 — notebook to model, all in-process (zero file I/O):
|
|
140
|
+
session = prepro_auto.launch(df)
|
|
141
|
+
# ...clean visually in the browser...
|
|
142
|
+
X = session.current().drop(columns=["target"])
|
|
143
|
+
y = session.current()["target"]
|
|
144
|
+
model.fit(X, y)
|
|
145
|
+
|
|
146
|
+
# Workflow 2 — clean once, productionize with the exported pipeline:
|
|
147
|
+
# 1) export pipeline.py from the workbench
|
|
148
|
+
# 2) commit pipeline.py to your model repo
|
|
149
|
+
# 3) in production: subprocess.run(["python", "pipeline.py", "incoming.csv", "ready.csv"])
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Methods
|
|
155
|
+
|
|
156
|
+
Field-standard methods throughout: MICE / KNN / median imputation, IQR + MAD + Isolation Forest for outliers, normality-driven scaling (Standard / Robust / Box-Cox / Yeo-Johnson), label / ordinal / one-hot / frequency / target encoding. No accuracy compromises — the same algorithms a data scientist would write by hand.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## AI providers (optional)
|
|
161
|
+
|
|
162
|
+
AI features are **optional**. Everything works offline without a key. PrePro Auto supports five providers:
|
|
163
|
+
|
|
164
|
+
| Provider | ID | Install | Get a key |
|
|
165
|
+
|---|---|---|---|
|
|
166
|
+
| Groq (free tier, fast) | `groq` | `pip install prepro-auto[groq]` | https://console.groq.com |
|
|
167
|
+
| OpenAI / GPT | `openai` | `pip install prepro-auto[openai]` | https://platform.openai.com |
|
|
168
|
+
| Anthropic Claude | `anthropic` | `pip install prepro-auto[anthropic]` | https://console.anthropic.com |
|
|
169
|
+
| Google Gemini | `gemini` | `pip install prepro-auto[gemini]` | https://aistudio.google.com/app/apikey |
|
|
170
|
+
| Mistral | `mistral` | `pip install prepro-auto[mistral]` | https://console.mistral.ai |
|
|
171
|
+
|
|
172
|
+
Or install all five at once: `pip install prepro-auto[ai]`.
|
|
173
|
+
|
|
174
|
+
### Three ways to give PrePro Auto your API key
|
|
175
|
+
|
|
176
|
+
**1. From the notebook (in-memory, session-only — safest):**
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
import prepro_auto
|
|
180
|
+
prepro_auto.set_api_key("openai", "sk-...") # any of the 5 provider IDs
|
|
181
|
+
session = prepro_auto.launch(df)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
The key lives only in the running process. Lost on restart (re-enter next session). PrePro Auto makes a tiny test call before returning, so you know immediately whether the key works.
|
|
185
|
+
|
|
186
|
+
**2. From the web UI (in-memory by default, optional .env persistence):**
|
|
187
|
+
|
|
188
|
+
In the workbench, click **"AI settings (API key)"** in the side rail. Pick a provider, paste the key, click **Test & apply**. PrePro Auto verifies the key with a live test call before accepting it. Tick **"Also save to .env"** if you want it to survive restarts (local convenience only — leave unchecked on any shared/hosted machine).
|
|
189
|
+
|
|
190
|
+
**3. From a `.env` file (persists across restarts):**
|
|
191
|
+
|
|
192
|
+
Add to `.env` in the project root:
|
|
193
|
+
```bash
|
|
194
|
+
LLM_PROVIDER=openai
|
|
195
|
+
OPENAI_API_KEY=sk-...
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Each provider has its own env-key name: `GROQ_API_KEY`, `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, `MISTRAL_API_KEY`.
|
|
199
|
+
|
|
200
|
+
**Honest security note:** the `.env` file is plain text. Fine for a personal machine; never use the persist option on a hosted/shared deployment until proper per-user auth is in place.
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Notebook API reference
|
|
205
|
+
|
|
206
|
+
After `import prepro_auto`, these are the top-level functions:
|
|
207
|
+
|
|
208
|
+
| Function | What it does |
|
|
209
|
+
|---|---|
|
|
210
|
+
| `prepro_auto.launch(df, domain="general", port=None, open_browser=False)` | Registers an in-memory DataFrame as a job (no upload), starts the local workbench server, returns a `Session`. Prints a clickable URL. |
|
|
211
|
+
| `prepro_auto.set_api_key(provider, api_key, model=None)` | Sets the AI provider and key at runtime (in-memory). Returns `{ok, provider, model, verified, reason}` after a live test call. |
|
|
212
|
+
|
|
213
|
+
After `session = prepro_auto.launch(df)`:
|
|
214
|
+
|
|
215
|
+
| Method / property | What it does |
|
|
216
|
+
|---|---|
|
|
217
|
+
| `session.current()` | Returns the current (active-version) DataFrame as it stands in the UI right now. |
|
|
218
|
+
| `session.update(df)` | Pushes a notebook-edited DataFrame to the UI as a new undoable version. |
|
|
219
|
+
| `session.url` | The workbench URL for this session. |
|
|
220
|
+
| `session.job_id` | The internal job ID for this session. |
|
|
221
|
+
| `session.port` | The local port the workbench server is running on. |
|
|
222
|
+
|
|
223
|
+
Typical sync cycle:
|
|
224
|
+
|
|
225
|
+
```python
|
|
226
|
+
cur = session.current() # pull current state from UI
|
|
227
|
+
cur["price_per_sqft"] = cur["price"] / cur["sqft"] # your own code
|
|
228
|
+
session.update(cur) # push back, refresh UI to see it
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## REST API reference
|
|
234
|
+
|
|
235
|
+
The web app and SDK both call the same endpoints, all under `/api/v1`. Once the server is running, the live interactive docs are at `http://localhost:8000/docs`.
|
|
236
|
+
|
|
237
|
+
| Endpoint | Purpose |
|
|
238
|
+
|---|---|
|
|
239
|
+
| `POST /datasets/upload` | Upload a dataset |
|
|
240
|
+
| `GET /datasets/{job_id}/preview` | First rows + shape |
|
|
241
|
+
| `POST /datasets/{job_id}/profile` | Per-column profile + quality score |
|
|
242
|
+
| `GET /datasets/{job_id}/view` | The current (active-version) data |
|
|
243
|
+
| `GET /datasets/{job_id}/comparison` | Raw vs current summary |
|
|
244
|
+
| `POST /datasets/{job_id}/stages/{stage}` | Run a cleaning stage (`missing_values`, `outliers`, `scaling`, `correlation`, `encoding`) |
|
|
245
|
+
| `POST /datasets/{job_id}/stages/{stage}/execute` | Apply approved decisions, commit a snapshot |
|
|
246
|
+
| `GET /datasets/{job_id}/decisions` | List decision cards (filter by `?stage=`) |
|
|
247
|
+
| `POST /decisions/{id}/approve` · `/override` · `/skip` · `/drop-column` | Resolve a card |
|
|
248
|
+
| `GET /datasets/{job_id}/queue` | Decision summary across stages |
|
|
249
|
+
| `GET /datasets/{job_id}/history` · `POST /undo` · `POST /redo` | Version history & navigation |
|
|
250
|
+
| `GET /datasets/{job_id}/snapshots` | List committed versions |
|
|
251
|
+
| `GET /datasets/{job_id}/transform/operations` | List available preset ops |
|
|
252
|
+
| `POST /datasets/{job_id}/transform/preset` | Apply a preset op (rename, drop, cast, fillna, filter, …) |
|
|
253
|
+
| `POST /datasets/{job_id}/transform/expression` | Run a sandboxed pandas expression |
|
|
254
|
+
| `POST /datasets/{job_id}/transform/batch` | Apply one op to many columns as one undoable step |
|
|
255
|
+
| `POST /datasets/{job_id}/transform/ai-propose` · `ai-advise` · `assistant` · `chat` | AI helpers (needs a key) |
|
|
256
|
+
| `POST /datasets/{job_id}/viz/chart` · `metric` · `compare` · `ask` | Charts and condition counts |
|
|
257
|
+
| `GET /datasets/{job_id}/viz/dashboard` | Before/after KPI dashboard |
|
|
258
|
+
| `POST /drift/compare` | Drift detection between two uploaded datasets |
|
|
259
|
+
| `GET /datasets/{job_id}/export/data` · `audit` · `pipeline` | Clean data, audit PDF, reproducible script |
|
|
260
|
+
| `GET /api/v1/system/limits` | Live RAM-aware upload limits |
|
|
261
|
+
| `GET /api/v1/system/llm` | List available providers + active one |
|
|
262
|
+
| `POST /api/v1/system/llm/configure` | Set provider + key at runtime |
|
|
263
|
+
|
|
264
|
+
Open `http://localhost:8000/docs` after `prepro_auto` is running for the interactive Swagger UI with full request/response schemas.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## License
|
|
269
|
+
|
|
270
|
+
MIT
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# PrePro Auto
|
|
2
|
+
|
|
3
|
+
**AI-assisted tabular data preprocessing with human-in-the-loop control.**
|
|
4
|
+
|
|
5
|
+
Profile, clean, transform, and export any tabular dataset — from a Jupyter notebook or a local web UI — with every step undoable, auditable, and reproducible. The same engine drives both interfaces, so results are identical wherever you call it from.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install prepro-auto
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> Author: [Shivanshu Pandey](https://github.com/Chilliflex) · Source: [github.com/Chilliflex/prepro_auto](https://github.com/Chilliflex/prepro_auto)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Quickstart — Notebook (no upload)
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
import pandas as pd
|
|
19
|
+
import prepro_auto
|
|
20
|
+
|
|
21
|
+
df = pd.read_csv("your_data.csv")
|
|
22
|
+
session = prepro_auto.launch(df) # opens the local workbench, NO upload
|
|
23
|
+
# -> click the printed http://127.0.0.1:8721/workbench?job=... link
|
|
24
|
+
|
|
25
|
+
# clean visually in the browser, then back in the notebook:
|
|
26
|
+
cleaned = session.current() # the UI-edited DataFrame
|
|
27
|
+
session.update(cleaned) # push notebook edits back to the UI
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
That's the whole loop. Your DataFrame is loaded directly from the notebook's memory — no file upload, no context switch. `df` (your original) never changes; `session.current()` always returns the latest cleaned version.
|
|
31
|
+
|
|
32
|
+
## Quickstart — Web UI
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
prepro_auto # starts the workbench at http://127.0.0.1:8000
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then open `http://127.0.0.1:8000/workbench` and upload a file.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## What it does
|
|
43
|
+
|
|
44
|
+
- **Profile** — per-column type inference, missing rates, 0–100 quality score
|
|
45
|
+
- **Clean (guided)** — missing values, outliers, scaling, correlation/leakage, encoding; each issue becomes a reviewable decision with a recommended action and alternatives
|
|
46
|
+
- **Transform (manual)** — 17 preset ops, sandboxed expressions, multi-column batches
|
|
47
|
+
- **AI assistant** — optional; describe a change in plain English; confirms intent and shows a real preview before applying
|
|
48
|
+
- **Visualize & dashboard** — histograms, bar, scatter charts, plus a before/after dashboard with KPI tiles and per-column comparison
|
|
49
|
+
- **Data drift** — compare two datasets to detect distribution shifts (PSI + KS)
|
|
50
|
+
- **Undo/redo** — every change is a version
|
|
51
|
+
- **Export** — clean data (CSV/Parquet), audit PDF, and a runnable Python pipeline script
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## What you get out of PrePro Auto
|
|
56
|
+
|
|
57
|
+
Five concrete outputs you can take away after a session. Each one is designed to plug straight into a real-world workflow:
|
|
58
|
+
|
|
59
|
+
| Output | What it is | Where to use it |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| **Cleaned DataFrame** | The in-memory DataFrame after all your cleaning + transforms, returned by `session.current()` in the notebook | Feed straight into `model.fit(X, y)` for scikit-learn, XGBoost, LightGBM, PyTorch, TensorFlow. No file I/O needed. |
|
|
62
|
+
| **Cleaned dataset file** | A CSV or Parquet file via `GET /datasets/{job_id}/export/data?format=csv` (or `format=parquet`) | Share with teammates, upload to a feature store, load into BI tools (Tableau, Power BI, Looker), commit to a versioned data repo, or feed into downstream ETL jobs. Parquet is smaller and faster for large datasets. |
|
|
63
|
+
| **Audit PDF** | A multi-page PDF via `GET /datasets/{job_id}/export/audit` listing every transformation with its parameters, before/after stats, and who approved it | Compliance trail for regulated industries (finance, healthcare, insurance); attach to a model-card or experiment-tracking entry; hand to a reviewer or data-governance team to prove the cleaning is reproducible and reasoned, not arbitrary. |
|
|
64
|
+
| **Runnable Python pipeline** | A standalone `.py` script via `GET /datasets/{job_id}/export/pipeline` that reproduces the exact cleaning with pandas + scikit-learn — no PrePro Auto dependency | Drop into a production training pipeline, an Airflow/Prefect/Dagster DAG, a CI job, or a coworker's machine. They run `python pipeline.py raw.csv clean.csv` and get the same result you produced visually. |
|
|
65
|
+
| **Drift report** | A per-column JSON verdict (PSI, KS test, severity bands) via `POST /drift/compare` between two datasets | Monitor a deployed model — compare last month's input distribution to this month's. Catch silent data shifts (a new product category, a sensor recalibration, a market regime change) before they degrade model performance. Plug into a monitoring dashboard or alert on `overall_verdict == "significant_drift"`. |
|
|
66
|
+
|
|
67
|
+
**Two common workflows:**
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
# Workflow 1 — notebook to model, all in-process (zero file I/O):
|
|
71
|
+
session = prepro_auto.launch(df)
|
|
72
|
+
# ...clean visually in the browser...
|
|
73
|
+
X = session.current().drop(columns=["target"])
|
|
74
|
+
y = session.current()["target"]
|
|
75
|
+
model.fit(X, y)
|
|
76
|
+
|
|
77
|
+
# Workflow 2 — clean once, productionize with the exported pipeline:
|
|
78
|
+
# 1) export pipeline.py from the workbench
|
|
79
|
+
# 2) commit pipeline.py to your model repo
|
|
80
|
+
# 3) in production: subprocess.run(["python", "pipeline.py", "incoming.csv", "ready.csv"])
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Methods
|
|
86
|
+
|
|
87
|
+
Field-standard methods throughout: MICE / KNN / median imputation, IQR + MAD + Isolation Forest for outliers, normality-driven scaling (Standard / Robust / Box-Cox / Yeo-Johnson), label / ordinal / one-hot / frequency / target encoding. No accuracy compromises — the same algorithms a data scientist would write by hand.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## AI providers (optional)
|
|
92
|
+
|
|
93
|
+
AI features are **optional**. Everything works offline without a key. PrePro Auto supports five providers:
|
|
94
|
+
|
|
95
|
+
| Provider | ID | Install | Get a key |
|
|
96
|
+
|---|---|---|---|
|
|
97
|
+
| Groq (free tier, fast) | `groq` | `pip install prepro-auto[groq]` | https://console.groq.com |
|
|
98
|
+
| OpenAI / GPT | `openai` | `pip install prepro-auto[openai]` | https://platform.openai.com |
|
|
99
|
+
| Anthropic Claude | `anthropic` | `pip install prepro-auto[anthropic]` | https://console.anthropic.com |
|
|
100
|
+
| Google Gemini | `gemini` | `pip install prepro-auto[gemini]` | https://aistudio.google.com/app/apikey |
|
|
101
|
+
| Mistral | `mistral` | `pip install prepro-auto[mistral]` | https://console.mistral.ai |
|
|
102
|
+
|
|
103
|
+
Or install all five at once: `pip install prepro-auto[ai]`.
|
|
104
|
+
|
|
105
|
+
### Three ways to give PrePro Auto your API key
|
|
106
|
+
|
|
107
|
+
**1. From the notebook (in-memory, session-only — safest):**
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
import prepro_auto
|
|
111
|
+
prepro_auto.set_api_key("openai", "sk-...") # any of the 5 provider IDs
|
|
112
|
+
session = prepro_auto.launch(df)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The key lives only in the running process. Lost on restart (re-enter next session). PrePro Auto makes a tiny test call before returning, so you know immediately whether the key works.
|
|
116
|
+
|
|
117
|
+
**2. From the web UI (in-memory by default, optional .env persistence):**
|
|
118
|
+
|
|
119
|
+
In the workbench, click **"AI settings (API key)"** in the side rail. Pick a provider, paste the key, click **Test & apply**. PrePro Auto verifies the key with a live test call before accepting it. Tick **"Also save to .env"** if you want it to survive restarts (local convenience only — leave unchecked on any shared/hosted machine).
|
|
120
|
+
|
|
121
|
+
**3. From a `.env` file (persists across restarts):**
|
|
122
|
+
|
|
123
|
+
Add to `.env` in the project root:
|
|
124
|
+
```bash
|
|
125
|
+
LLM_PROVIDER=openai
|
|
126
|
+
OPENAI_API_KEY=sk-...
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Each provider has its own env-key name: `GROQ_API_KEY`, `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, `MISTRAL_API_KEY`.
|
|
130
|
+
|
|
131
|
+
**Honest security note:** the `.env` file is plain text. Fine for a personal machine; never use the persist option on a hosted/shared deployment until proper per-user auth is in place.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Notebook API reference
|
|
136
|
+
|
|
137
|
+
After `import prepro_auto`, these are the top-level functions:
|
|
138
|
+
|
|
139
|
+
| Function | What it does |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `prepro_auto.launch(df, domain="general", port=None, open_browser=False)` | Registers an in-memory DataFrame as a job (no upload), starts the local workbench server, returns a `Session`. Prints a clickable URL. |
|
|
142
|
+
| `prepro_auto.set_api_key(provider, api_key, model=None)` | Sets the AI provider and key at runtime (in-memory). Returns `{ok, provider, model, verified, reason}` after a live test call. |
|
|
143
|
+
|
|
144
|
+
After `session = prepro_auto.launch(df)`:
|
|
145
|
+
|
|
146
|
+
| Method / property | What it does |
|
|
147
|
+
|---|---|
|
|
148
|
+
| `session.current()` | Returns the current (active-version) DataFrame as it stands in the UI right now. |
|
|
149
|
+
| `session.update(df)` | Pushes a notebook-edited DataFrame to the UI as a new undoable version. |
|
|
150
|
+
| `session.url` | The workbench URL for this session. |
|
|
151
|
+
| `session.job_id` | The internal job ID for this session. |
|
|
152
|
+
| `session.port` | The local port the workbench server is running on. |
|
|
153
|
+
|
|
154
|
+
Typical sync cycle:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
cur = session.current() # pull current state from UI
|
|
158
|
+
cur["price_per_sqft"] = cur["price"] / cur["sqft"] # your own code
|
|
159
|
+
session.update(cur) # push back, refresh UI to see it
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## REST API reference
|
|
165
|
+
|
|
166
|
+
The web app and SDK both call the same endpoints, all under `/api/v1`. Once the server is running, the live interactive docs are at `http://localhost:8000/docs`.
|
|
167
|
+
|
|
168
|
+
| Endpoint | Purpose |
|
|
169
|
+
|---|---|
|
|
170
|
+
| `POST /datasets/upload` | Upload a dataset |
|
|
171
|
+
| `GET /datasets/{job_id}/preview` | First rows + shape |
|
|
172
|
+
| `POST /datasets/{job_id}/profile` | Per-column profile + quality score |
|
|
173
|
+
| `GET /datasets/{job_id}/view` | The current (active-version) data |
|
|
174
|
+
| `GET /datasets/{job_id}/comparison` | Raw vs current summary |
|
|
175
|
+
| `POST /datasets/{job_id}/stages/{stage}` | Run a cleaning stage (`missing_values`, `outliers`, `scaling`, `correlation`, `encoding`) |
|
|
176
|
+
| `POST /datasets/{job_id}/stages/{stage}/execute` | Apply approved decisions, commit a snapshot |
|
|
177
|
+
| `GET /datasets/{job_id}/decisions` | List decision cards (filter by `?stage=`) |
|
|
178
|
+
| `POST /decisions/{id}/approve` · `/override` · `/skip` · `/drop-column` | Resolve a card |
|
|
179
|
+
| `GET /datasets/{job_id}/queue` | Decision summary across stages |
|
|
180
|
+
| `GET /datasets/{job_id}/history` · `POST /undo` · `POST /redo` | Version history & navigation |
|
|
181
|
+
| `GET /datasets/{job_id}/snapshots` | List committed versions |
|
|
182
|
+
| `GET /datasets/{job_id}/transform/operations` | List available preset ops |
|
|
183
|
+
| `POST /datasets/{job_id}/transform/preset` | Apply a preset op (rename, drop, cast, fillna, filter, …) |
|
|
184
|
+
| `POST /datasets/{job_id}/transform/expression` | Run a sandboxed pandas expression |
|
|
185
|
+
| `POST /datasets/{job_id}/transform/batch` | Apply one op to many columns as one undoable step |
|
|
186
|
+
| `POST /datasets/{job_id}/transform/ai-propose` · `ai-advise` · `assistant` · `chat` | AI helpers (needs a key) |
|
|
187
|
+
| `POST /datasets/{job_id}/viz/chart` · `metric` · `compare` · `ask` | Charts and condition counts |
|
|
188
|
+
| `GET /datasets/{job_id}/viz/dashboard` | Before/after KPI dashboard |
|
|
189
|
+
| `POST /drift/compare` | Drift detection between two uploaded datasets |
|
|
190
|
+
| `GET /datasets/{job_id}/export/data` · `audit` · `pipeline` | Clean data, audit PDF, reproducible script |
|
|
191
|
+
| `GET /api/v1/system/limits` | Live RAM-aware upload limits |
|
|
192
|
+
| `GET /api/v1/system/llm` | List available providers + active one |
|
|
193
|
+
| `POST /api/v1/system/llm/configure` | Set provider + key at runtime |
|
|
194
|
+
|
|
195
|
+
Open `http://localhost:8000/docs` after `prepro_auto` is running for the interactive Swagger UI with full request/response schemas.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## License
|
|
200
|
+
|
|
201
|
+
MIT
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Aggregates all route modules into a single APIRouter that main.py mounts
|
|
3
|
+
under the API_PREFIX (e.g. /api/v1).
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from fastapi import APIRouter
|
|
7
|
+
|
|
8
|
+
from app.api.routes import health, datasets, decisions, execution, export, transform
|
|
9
|
+
|
|
10
|
+
api_router = APIRouter()
|
|
11
|
+
api_router.include_router(health.router)
|
|
12
|
+
api_router.include_router(datasets.router)
|
|
13
|
+
api_router.include_router(decisions.router)
|
|
14
|
+
api_router.include_router(execution.router)
|
|
15
|
+
api_router.include_router(export.router)
|
|
16
|
+
api_router.include_router(transform.router)
|
|
File without changes
|