Table of Contents
Navigation
Why PhronesisML
| Notebooks | AutoML Tools | PhronesisML | |
|---|---|---|---|
| Structure | Ad hoc, cell-by-cell | Fixed, opaque | Modular agents on typed WorkflowState |
| Transparency | High, but unorganized | Low — black box | High — every decision is inspectable |
| Overridable | N/A | Rarely | Yes — imputation, encoding, model choice |
| Reusable | Low | Low | High — same pipeline, swap the data |
| Production-ready | No | Partially | Yes — versioned, reportable artifacts |
| Works offline | Yes | Rarely | Yes — by design |
In short: PhronesisML recommends; it does not obscure. Every stage of the pipeline is a discrete, testable, reusable unit of code operating on a shared, typed
WorkflowState.
PhronesisML is an SDK-first and CLI-first offline Machine Learning Engineering SDK. The Python SDK — and the CLI built on it — are the canonical interfaces; any future GUI would be a thin client over the same SDK a data scientist would import directly. There is exactly one source of truth for ML logic.
Core Principles
PhronesisML is built around five commitments that shape every design decision in the codebase:
| Principle | What It Means in Practice |
|---|---|
| Simple API | Phronesis("data.csv").run() is a complete, working pipeline. Complexity is opt-in, not mandatory. |
| Advanced Power | The same SDK exposes stage-by-stage control, custom configuration, and low-level workflow access when you need it. |
| Offline-First | The core pipeline runs with no network dependency — your data never has to leave your machine to be analyzed. |
| Production-Ready | Every run produces versioned, structured artifacts, not a throwaway notebook cell. |
| Intelligent Automation | Engine selection, target detection, and model recommendation are automated but always inspectable and overridable. |
Key Features
Multi-Agent |
Orchestration |
Auto Engine |
Cleaning |
Analysis |
Engineering |
Detection |
Selection |
Metrics |
Explainability |
Reporting |
Extensible |
| Feature | Description | Status |
|---|---|---|
| Multi-Agent Workflow | Each pipeline stage is an independent agent with a single responsibility | ✅ |
| LangGraph Orchestration | Agents are nodes in a directed graph; state passing, retries | ✅ |
| Automatic Engine Selection | Dataset size determines Pandas, Polars, or PySpark | ✅ |
| ETL | Declarative extraction, cleaning, and transformation | ✅ |
| Validation | Schema, type, and quality validation before downstream processing | ✅ |
| EDA | Automated statistical profiling and structured dataset summaries | ✅ |
| Feature Engineering | Automated and configurable transformation, encoding, derivation | ✅ |
| Target Detection | Heuristic, overridable identification of prediction target | ✅ |
| Model Recommendation | Rule- and metric-driven suggestion of candidate model families | ✅ |
| Clustering | Auto-selected clustering (KMeans / DBSCAN / Agglomerative) with silhouette scoring | ✅ |
| Anomaly Detection | Auto-selected Isolation Forest / LOF with labels and scores | ✅ |
| Explainability | Post-training feature importance and model-behavior summaries | ✅ |
| Reporting | Structured, versionable output artifacts for every stage | ✅ |
| Offline-First | Core pipeline stages run without network access | ✅ |
| SDK-First | Every interface is a client of the SDK | ✅ |
| Plugin System | Extension points for custom agents, models, engines, storage | 🔜 Planned |
Architecture Overview
graph TD
A["Python SDK<br/>Phronesis class"] --> B
B["LangGraph Workflow<br/>Orchestrates agents"] --> C
C["Agents<br/>One responsibility each"] --> D
D["Services<br/>Reusable domain logic"] --> E
E["Data Engines<br/>Pandas / Polars / PySpark"] --> F
F["Reports / Storage<br/>Persisted artifacts"]
style A fill:#6366F1,stroke:#4F46E5,color:#fff,stroke-width:2px
style B fill:#A855F7,stroke:#9333EA,color:#fff,stroke-width:2px
style C fill:#EC4899,stroke:#DB2777,color:#fff,stroke-width:2px
style D fill:#14B8A6,stroke:#0D9488,color:#fff,stroke-width:2px
style E fill:#F97316,stroke:#EA580C,color:#fff,stroke-width:2px
style F fill:#06B6D4,stroke:#0891B2,color:#fff,stroke-width:2px
| Layer | Responsibility | Depends On |
|---|---|---|
| Python SDK | Single public entry point (Phronesis class) |
— |
| LangGraph Workflow | Pipeline as graph; owns WorkflowState |
Called by SDK |
| Agents | One pipeline responsibility each; read/write state | Graph nodes |
| Services | Stateless, reusable domain logic | Called by agents |
| Data Engines | Pandas, Polars, PySpark implementations | Called by services |
| Reports / Storage | Persists run artifacts | Written to by agents |
Design Principles
| Principle | What It Means |
|---|---|
| SDK-first | One source of truth for ML logic |
| Offline-first | Core pipeline runs without network |
| Deterministic ML | Same input + config = same output |
| Dependency Injection | Agents receive dependencies rather than construct them |
| Clean Architecture | Layers depend inward, never outward |
| Single Responsibility | One agent, one job |
| Strategy Pattern | Interchangeable engine selection |
How It Works
graph TD
A["1. Dataset Upload"] --> B["2. ETL / Cleaning"]
B --> C["3. Validation"]
C --> D["4. EDA & Profiling"]
D --> E["5. Target Detection"]
E --> F["6. Feature Engineering"]
F --> G["7. Model Recommendation & Training"]
G --> H["8. Evaluation"]
H --> I["9. Explainability"]
I --> J["10. Reporting"]
J --> K["11. Storage"]
style A fill:#6366F1,color:#fff
style B fill:#0EA5E9,color:#fff
style C fill:#EF4444,color:#fff
style D fill:#F97316,color:#fff
style E fill:#EF4444,color:#fff
style F fill:#EAB308,color:#000
style G fill:#8B5CF6,color:#fff
style H fill:#14B8A6,color:#fff
style I fill:#EC4899,color:#fff
style J fill:#06B6D4,color:#fff
style K fill:#10B981,color:#fff
Each numbered stage is implemented as its own agent — see Project Structure for where each one lives in the codebase.
Engine Selection Logic
PhronesisML supports three interchangeable dataframe backends behind a single DataEngine interface, so pipeline code never imports Pandas, Polars, or PySpark directly.
graph LR
A["Dataset"] --> B{"Profile size<br/>& shape"}
B -->|"Small–medium,<br/>fits in memory"| C["Pandas"]
B -->|"Larger,<br/>single machine"| D["Polars"]
B -->|"Larger than<br/>memory / distributed"| E["PySpark"]
C --> F["Same DataEngine<br/>interface downstream"]
D --> F
E --> F
style A fill:#6366F1,color:#fff
style B fill:#A855F7,color:#fff
style C fill:#150458,color:#fff
style D fill:#CD792C,color:#fff
style E fill:#E25A1C,color:#fff
style F fill:#06B6D4,color:#fff
| Engine | Best For | Why |
|---|---|---|
| Pandas | Small-to-medium, in-memory | Ubiquitous, well understood |
| Polars | Larger single-machine workloads | Rust-based, multi-threaded query engine |
| PySpark | Distributed / larger-than-memory data | Industry standard at scale |
Selection is automatic by default but can always be forced explicitly — see Quick Start.
Technology Stack
Performance
PhronesisML's engine abstraction exists specifically so the pipeline can move from Pandas to Polars to PySpark as data size grows, without changing pipeline code. Formal, reproducible benchmarks across dataset sizes and engines are not yet published — this section will be filled in with measured numbers (not estimates) once a benchmark suite lands. Track progress in Roadmap.
Installation
Standard (recommended)
pip install phronesisml
Supported file formats
| Format | Supported | Dependency |
|---|---|---|
| CSV / TSV | ✅ | pandas (core) |
| Excel (.xlsx) | ✅ | openpyxl ([excel] extra) |
| Parquet | ✅ | pyarrow (core) |
| JSON / JSONL | ✅ | pandas (core) |
| Feather / Arrow | ✅ | pyarrow (core) |
Optional extras
| Extra | Install | What it adds |
|---|---|---|
all |
pip install phronesisml[all] |
Everything below |
cli |
pip install phronesisml[cli] |
CLI commands |
excel |
pip install phronesisml[excel] |
Excel (.xlsx) support via openpyxl |
mlflow |
pip install phronesisml[mlflow] |
MLflow tracking |
spark |
pip install phronesisml[spark] |
PySpark engine |
docs |
pip install phronesisml[docs] |
Build the project docs (mkdocs + mkdocstrings) |
dev |
pip install phronesisml[dev] |
pytest (+ xdist), ruff, mypy, coverage, build, twine |
From source
git clone https://github.com/kartik00052/PhronesisML.git
cd PhronesisML
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
Using uv?
uv sync --all-extrascreates the environment from the committeduv.lock(reproducible install), anduv buildproduces the wheel + sdist. Both pip and uv are first-class, CI-validated workflows.
Quick Start
SDK (Python)
from phronesisml import Phronesis
ml = Phronesis("data/customers.csv")
ml.run()
print(ml.report())
CLI
phronesisml run data/customers.csv
phronesisml run data/customers.csv --engine polars
phronesisml info
Examples
Incremental Usage
from phronesisml import Phronesis
ml = Phronesis("data/customers.csv")
ml.load()
print(ml.summary())
ml.clean(null_strategy="fill")
ml.validate()
ml.eda()
ml.detect_target()
result = ml.train()
print(f"Best model: {result.model_type} ({result.score:.4f})")
print(ml.evaluate())
print(ml.explain())
Simple API (one-liner functions)
from phronesisml import analyze, train
profile = analyze("data/customers.csv")
print(f"{profile.shape[0]} rows, {profile.shape[1]} columns")
result = train("data/customers.csv")
print(f"Best model: {result.best_model_type} ({result.best_score:.4f})")
Unsupervised — clustering & anomaly detection
from phronesisml import cluster, detect_anomalies
clusters = cluster("data/customers.csv")
print(f"Algorithm: {clusters.algorithm}, Clusters: {clusters.n_clusters}")
anomalies = detect_anomalies("data/customers.csv", contamination=0.1)
print(f"Anomalies: {anomalies.n_anomalies} of {anomalies.n_total}")
Async variants
from phronesisml import analyze_async, train_async
import asyncio
async def main():
profile = await analyze_async("data/customers.csv")
result = await train_async("data/customers.csv")
asyncio.run(main())
Error handling
from phronesisml import train
from phronesisml.exceptions import DataValidationError, EngineSelectionError, WorkflowError
try:
result = train("data/customers.csv")
except DataValidationError as e:
print(f"Dataset failed validation: {e}")
except EngineSelectionError as e:
print(f"Could not select a data engine: {e}")
except WorkflowError as e:
print(f"Pipeline failed: {e}")
Advanced — low-level workflow API
import asyncio
from phronesisml import run_pipeline
async def main():
result = await run_pipeline(data_path="data/customers.csv")
print(result)
asyncio.run(main())
SDK Interfaces
PhronesisML is SDK-first and CLI-first: the CLI is a thin client that calls the same SDK you import directly.
| Interface | Install | Description |
|---|---|---|
| Python SDK | pip install phronesisml |
from phronesisml import Phronesis |
| CLI | pip install phronesisml[cli] |
phronesisml run data.csv |
Project Structure
phronesisml/
__init__.py # Public SDK surface
exceptions.py # Exception hierarchy
agents/ # Pipeline agents (11 total)
configs/ # Pydantic configuration
data/ # Data loading, validation, profiling
engines/ # Pandas/Polars/Spark abstraction
interfaces/ # CLI (Typer)
ml/ # Model definitions, training, metrics
rag/ # RAG infrastructure
workflow/ # LangGraph workflow orchestration
Offline-First Philosophy
PhronesisML's core pipeline — validation, profiling, ETL, EDA, feature engineering, target detection, model recommendation, training, evaluation, explainability, and reporting — runs entirely on your machine, with no network dependency and no requirement to send data to a hosted service. Optional extras (mlflow for remote experiment tracking, future cloud storage backends) are opt-in additions on top of an offline-capable core, not a requirement for it.
Security
- No data leaves your machine unless you explicitly configure a remote storage or tracking backend.
- No hidden network calls in the core pipeline — installation extras that do require network access (e.g.
mlflow) are opt-in. - Dependency-pinned releases to reduce supply-chain surface area.
- Found a security issue? Please open a private security advisory on GitHub rather than a public issue.
Roadmap
Completed
- Core
WorkflowState+ LangGraph orchestration - All 11 pipeline agents
- Pandas, Polars, PySpark engines with auto-selection
- Local filesystem storage
- CLI interface
- HTML report generation
- Clustering and anomaly detection flows (unsupervised)
- Full test suites
Planned
- Plugin system with entry-points discovery
- S3, GCS, Azure Blob storage backends
- DuckDB engine
- PDF report rendering
- Parallel/branching agent execution
- Reproducible benchmark suite (see Performance)
- Desktop GUI client
- Human-in-the-loop checkpoints
Contributing
make check # lint + typecheck + test
make format # auto-fix formatting
make build # build wheel + sdist
New to the project? Look for issues labeled good first issue. Please open an issue before starting on a large change, so the design can be discussed first.
Community
- GitHub Discussions — design questions, ideas, and general Q&A
- Issues — bug reports and feature requests
- Pull Requests — see what's currently in progress
FAQ
Why not just use AutoML?
AutoML tools optimize for a leaderboard metric and hide their reasoning. PhronesisML makes every decision inspectable and overridable.
Why LangGraph?
LangGraph models workflows as a graph of stateful nodes with conditional edges — a direct map onto PhronesisML's pipeline shape.
Why Polars in addition to Pandas?
Polars' Rust-based, multi-threaded engine handles larger workloads significantly faster. PhronesisML upgrades automatically when warranted — see Engine Selection Logic.
Can I run only part of the pipeline?
Yes — run() and run_pipeline() accept a stages parameter so you can run, for example, only validation and EDA.
Does PhronesisML require an internet connection?
No. The core pipeline is offline-first — see Offline-First Philosophy. Only optional extras like remote MLflow tracking require network access.
License
Licensed under the MIT License — see LICENSE for the full text.
Acknowledgements
PhronesisML's design draws inspiration from the architectural patterns and developer experience established by these projects, without any affiliation with or endorsement from them.
Metadata
Release files for phronesisml 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| phronesisml-0.3.1.tar.gz | 177.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| phronesisml-0.3.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 391.2 kB
Release files / phronesisml-0.3.1.tar.gz
| Download URL | phronesisml-0.3.1.tar.gz |
|---|---|
| Size | 177.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3428aae8d7f392093b0a403c7f06ec4c5280fe7152e42da3ee5439f6731845e2
|
|
BLAKE2b-256 checksum How to use checksums |
e669776537023ad9380bbb8d90336f62a27d5bccba15f7c757ec6d8c05bd5657
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / phronesisml-0.3.1-py3-none-any.whl
| Download URL | phronesisml-0.3.1-py3-none-any.whl |
|---|---|
| Size | 214.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b954e7a1760c49465f8323f77779404e697176a84a034ee3da445afa1f0e29df
|
|
BLAKE2b-256 checksum How to use checksums |
8b61234933b50713234ba6c158e99c1f48e127d4e70ac4eba98f8e1da8d43a7c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for phronesisml 0.3.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.