DSCraft: a unified, MIT-licensed, local-first ML tooling platform -- tabular AutoML, data cleaning, time-series forecasting, graph ML, computer vision, LLM fine-tuning, LLM/agent red-teaming, and agent/RAG benchmark eval, all as installable extras of one package. `core` is the thin shared substrate (data-tier conventions, OTel GenAI telemetry helpers, license-isolation policy, shared sandbox executor) used by every other dscraft subpackage.
Project description
dscraft
A unified, MIT-licensed, local-first ML tooling platform: tabular AutoML, data cleaning, time-series forecasting, graph ML, computer vision, LLM fine-tuning, LLM/agent red-teaming, and agent/RAG benchmark eval, all installed and imported as one real Python package — the way numpy or PyTorch ships one distribution with an internal module tree, not nine separately-installed packages.
pip install dscraft # base install: just dscraft.core
pip install "dscraft[automl]" # + dscraft.automl's runtime deps
pip install "dscraft[all]" # every subpackage's runtime deps
import dscraft.core # always available
import dscraft.automl # available once installed with the `automl` extra
Each subpackage below is a scaffold-depth pass: a real, working slice
of its eventual scope (per DSCraft_Unified_Architecture.md), not a full
implementation. See that document for the full architecture, locked
design decisions, and per-module roadmap; this README only orients you to
what's here today and how to install/run it.
Subpackages
| Subpackage | Extra | What it does |
|---|---|---|
dscraft.core |
(base install) | Shared substrate: three-tier data conventions, OTel GenAI telemetry helpers, license-isolation policy, shared sandbox executor. |
dscraft.automl |
automl (+ automl-onnx) |
Clean-room tabular AutoML — .compile() fuses a fitted sklearn.pipeline.Pipeline into one portable ONNX graph via skl2onnx; build_model/build_clusterer/build_resampler add selectable XGBoost/LightGBM/CatBoost, HDBSCAN, and imbalanced-learn backends. |
dscraft.clean |
clean |
Data-quality firewall — the composed Sanitizer entrypoint (DeCoLe label-error detection, train/test contamination auditing, Dataset Integrity Score), plus lower-level ONNX Runtime (PyTorch-free) text and image embeddings feeding cosine-similarity near-duplicate detection. |
dscraft.forecast |
forecast |
Classical statistical forecasting (13 statsforecast models: AutoARIMA/AutoETS/AutoCES/AutoTheta autofits, simple baselines, Croston) over a Tier-1 Arrow-backed pipeline, utilsforecast-scored backtesting, and standalone STL/MSTL (+ Box-Cox) decomposition. |
dscraft.graph |
graph |
Sparse graph ML — a concrete Tier-2 COO↔CSR/CSC tensor adapter (PyG↔SciPy) plus a minimal GCN forward pass. |
dscraft.vision |
vision |
Computer vision — a concrete Tier-3 dense image pipeline (decode→augment→tensor) plus a small CNN exported via torch.export()→ONNX, plus run_ocr() with selectable EasyOCR/Tesseract backends. |
dscraft.tune |
tune |
Local LLM fine-tuning — an Adapter-Factory BaseTrainingAdapter interface with a ProgrammaticAdapter doing real (tiny) LoRA fine-tuning via peft/transformers. |
dscraft.security |
security |
LLM red-teaming — a BaseSecurityAdapter running a real prompt-injection probe/detector loop against a local target inside the shared sandbox, OWASP-mapped findings. |
dscraft.agent |
agent |
Agent/benchmark eval — a bring-your-own-agent AgentAdapter executing file-manipulation tool-use tasks inside the shared sandbox, scored for pass rate and latency. |
dscraft.eda |
eda (+ eda-plotnine) |
Exploratory data analysis — a lazy Polars profiling engine, HLL/KLL sketches, a mixed-type association matrix, and a self-contained HTML/Canvas report, composed behind one LazyEDA entry point; optional plotnine-based association_heatmap/column_distribution static plots via the separate eda-plotnine extra. |
Installation
# Base install — just dscraft.core (opentelemetry-api only)
pip install dscraft
# One subpackage's runtime deps
pip install "dscraft[forecast]"
# AutoML's optional ONNX export path (on top of the `automl` extra)
pip install "dscraft[automl,automl-onnx]"
# EDA's optional plotnine static-plot path (on top of the `eda` extra)
pip install "dscraft[eda,eda-plotnine]"
# Everything (all nine subpackages' runtime deps)
pip install "dscraft[all]"
Local development
cd /path/to/this/repo
pip install -e "packages/dscraft[dev,all]"
pytest packages/dscraft/tests
dev adds pytest plus test-only dependencies (pandas, polars,
pyarrow, statsmodels) that some subpackages' test suites need but
their runtime code does not. dev is deliberately kept free of any
"heavy" dependency (torch, onnx, transformers, scikit-learn) so that
pip install -e "packages/dscraft[dev]" alone stays minimal — those only
come in via a subpackage's own extra (e.g. automl, vision) or via
all. Installing all alongside dev is what lets the entire combined
test suite (all nine subpackages) run in one environment.
To run a single subpackage's tests in isolation, install just its extra:
pip install -e "packages/dscraft[forecast,dev]"
pytest packages/dscraft/tests/forecast
dscraft.vision's test suite is the one exception: its real-dataset
validation test uses sklearn.datasets.load_digits() (test-only, not a
vision runtime dependency), so running it in isolation needs
scikit-learn from somewhere — either add the automl extra
(dscraft[vision,automl,dev], since automl already depends on
scikit-learn) or install scikit-learn directly alongside
dscraft[vision,dev]. The full combined install (dscraft[all,dev])
always has it, via automl.
dscraft.core
The thin, shared substrate underneath every other subpackage: three-tier
data/tensor conventions (Tier 1 Arrow-backed pandas/Polars, Tier 2 sparse
graph tensor adapters, Tier 3 dense media pipelines), OpenTelemetry
GenAI-schema telemetry helpers, the license-isolation policy table and
model-tier allowlist mechanism, and the shared sandbox executor
(SandboxPolicy + BaseSandboxExecutor, with a real SeatbeltSandboxExecutor
on macOS) used by both dscraft.security and dscraft.agent. Its only
runtime dependency is opentelemetry-api; it never depends on pandas,
polars, torch, or any ML framework. Always installed — no extra needed.
dscraft.automl
dscraft.automl.compile() takes a fitted sklearn.pipeline.Pipeline
and returns a single, portable onnx.ModelProto via skl2onnx, fusing
every pipeline step into one graph loadable by onnxruntime with no
scikit-learn install required at serving time. Base runtime deps
(numpy, pandas, scikit-learn) install via the automl extra;
skl2onnx/onnx/onnxruntime (needed only for .compile() itself, and
lazily imported) install via the separate automl-onnx extra.
dscraft.automl.build_model(name, task, **kwargs) builds an unfitted,
sklearn-compatible gradient-boosted-tree estimator from a caller-selected
backend -- XGBoost, LightGBM, or CatBoost, all three equally supported per
this project's multi-backend design principle (none is a "default").
SUPPORTED_CLASSIFIERS/SUPPORTED_REGRESSORS are the name -> class
allowlists build_model dispatches through, mirroring
dscraft.forecast's SUPPORTED_MODELS pattern. All three libraries are
base runtime deps of the automl extra (not a separate extra).
dscraft.automl.build_clusterer(name, **kwargs) builds an unfitted,
sklearn-compatible clustering estimator -- currently HDBSCAN, via
scikit-learn's own built-in sklearn.cluster.HDBSCAN (no new dependency
needed), exposed through SUPPORTED_CLUSTERERS. This is an independent,
unsupervised capability -- it does not require the supervised model
allowlist above.
dscraft.automl.build_resampler(name, **kwargs) builds an unfitted
imbalanced-learn resampler -- RandomOverSampler, SMOTE, or
RandomUnderSampler, exposed through SUPPORTED_RESAMPLERS -- for
rebalancing a skewed classification training set ahead of the classifier
path above. imbalanced-learn is a base runtime dep of the automl
extra.
dscraft.clean
A data-quality firewall for a training DataFrame. The primary entrypoint is
Sanitizer, which composes three independently-implemented capabilities
into one audit-then-clean workflow:
- DeCoLe (
label_errors.py) — group-conditioned Confident Learning: per-(group, class) confidence thresholds instead of one global threshold, avoiding the standard confident-learning failure mode of over-pruning a lower-confidence-but-correctly-labeled group's examples. Pruning supports three selectable strategies mirroring cleanlab'sfind_label_issuesfilter modes —"noise_rate"(default),"class", and"both"(their intersection, viaprune_by_both) — added as part of a cleanlab parity audit. - Train/test contamination auditing (
contamination.py) — a two-stage pipeline: cheap LSHBloom MinHash/Bloom-filter candidate screening (viadatasketch) over every row, then optional Min-K%++ log-probability validation for stage-1 candidates (only run when the caller supplies precomputed per-token log-probabilities from a language model this module never runs itself). - Dataset Integrity Score (
integrity.py) — a single weighted scalar combining the label-error rate, the contamination rate, and train/test demographic-group drift (Jensen-Shannon divergence).
from dscraft.clean import Sanitizer
sanitizer = Sanitizer(train_df, target_col="text", label_col="label", group_col="group")
report = sanitizer.audit(test_df, out_of_sample_probs) # from your own k-fold CV
print(report.integrity_report.score) # 0.0 (worst) .. 1.0 (best)
cleaned_df = report.purge(strategy="demographic-preserving", output_path="cleaned.parquet")
report.purge()'s "demographic-preserving" strategy removes flagged
label-error rows and training rows matched to validated-contaminated test
items, while capping how much any single demographic group can be pruned
relative to the dataset-wide removal rate — see SanitizerReport.purge's
docstring for the exact, documented algorithm.
detect_near_duplicate_text remains available as the lower-level building
block it always was (ONNX Runtime, deliberately PyTorch-free, text
embeddings feeding cosine-similarity near-duplicate detection — a scaffold
of the LazyClean module's D4 semantic-dedup idea; the IVF-HNSW/spherical
k-means scale-out path is still out of scope, see dedup.py). Zero-vector
("no extractable features") rows are honestly reported as "not
comparable," distinct from both confirmed-duplicate and confirmed-distinct
pairs.
detect_near_duplicate_images is the image-modality counterpart: it embeds
a batch of already-decoded images via native ONNX Runtime (no PyTorch, no
CLIP-specific Python package — a Tier-2, opt-in-gated CLIP vision model per
image_dedup.py's model allowlist) and reuses dedup.py's same
modality-agnostic near-duplicate scan to flag near-duplicate image pairs.
Install via the clean extra.
dscraft.forecast
Classical statistical forecasting via Nixtla's statsforecast over a
Tier-1 Arrow-backed input pipeline, with a basic train/test backtest
reporting MAE/RMSE. SUPPORTED_MODELS covers the full classical catalog
statsforecast ships out of the box: autoregressive/exponential-smoothing
autofits (AutoARIMA, AutoETS, AutoCES, AutoTheta), simple baselines
(Naive, SeasonalNaive, RandomWalkWithDrift, HistoricAverage,
WindowAverage, SeasonalWindowAverage), and the Croston family for
intermittent-demand series (CrostonClassic, CrostonOptimized,
CrostonSBA) — zero new dependencies, since every one of these classes
already ships in statsforecast. Backtest MAE/RMSE are computed via
Nixtla's utilsforecast (the shared metrics/plotting/preprocessing-helper
layer the rest of the nixtlaverse already assumes) rather than
hand-rolled, so future backends added to this subpackage share one
canonical metric implementation. decompose() exposes STL/MSTL time
series decomposition (plus an optional Box-Cox transform) as a
standalone, inspectable diagnostic -- trend/seasonal/residual components
returned as a tidy long-format DataFrame, not folded silently into
forecast() -- via statsmodels/scipy, both already transitively
available in this extra. The tree-based ML branch, TSFM zero-shot branch,
self-healing preprocessing, and conformal-prediction leaderboard from the
full LazyForecast design are deferred. Install via the forecast extra.
In addition to the hermetic synthetic-panel tests and the statsmodels-
bundled co2/nile real-dataset validation, this subpackage's test suite
also validates forecast()/backtest() against a real published
forecasting-competition benchmark (the M3 competition's "Other" group) via
Nixtla's datasetsforecast -- a test-only dependency (like statsmodels)
that downloads its data over the network on first use and is skipped
(not failed) when offline; see
tests/forecast/test_datasetsforecast_validation.py.
dscraft.graph
PyGSparseAdapter is the first concrete implementation of
dscraft.core.data.SparseGraphTensorAdapter: a real COO↔CSR/CSC bridge
between PyTorch Geometric edge-index tensors and scipy.sparse, since
DLPack cannot represent sparsity. GCN is a minimal two-layer graph
convolutional network built on torch_geometric.nn.GCNConv that consumes
the adapter directly. Install via the graph extra.
dscraft.vision
SimpleImagePipeline is the first concrete implementation of
dscraft.core.data.DenseMediaPipeline (decode via Pillow → augment
resize/flip → dense torch.Tensor, DLPack-ready). TinyCNN is a small
LeNet-style classifier captured via torch.export() and exported to ONNX,
proving the export path end-to-end. run_ocr(image, backend=...) adds OCR
as a second, independent capability with a selectable backend — "easyocr"
(PyTorch-based, MPS/GPU-capable, no external binary) or "tesseract" (via
pytesseract, CPU-only, requires the separate system tesseract binary —
e.g. brew install tesseract on macOS) — per the multi-backend design
principle, neither is hard-coded as the only option. Both return a
comparably-shaped OCRResult (text plus per-detection bounding
boxes/confidence). Install via the vision extra (both OCR backends'
pip packages ship with it; the tesseract backend additionally needs the
system binary installed separately).
dscraft.tune
BaseTrainingAdapter is a minimal Adapter-Factory interface
(prepare/train_step/save_adapter); ProgrammaticAdapter is the one
concrete implementation, running a real (tiny) LoRA fine-tuning step on a
small local causal LM via peft + transformers — genuine forward +
backward + optimizer-step training, not a mock. Subprocess-isolated
adapters (torchtune/Axolotl), multi-fidelity BOHB tuning, and real
GGUF/MLX export are deferred. Install via the tune extra.
dscraft.security
A minimal, real, end-to-end slice of the LazyRed module: BaseSecurityAdapter
runs one probe (PromptInjectionAdapter) against a deliberately vulnerable
local target function, executed through the shared dscraft.core.sandbox
executor, with findings mapped to the OWASP LLM Top 10 and reported via
dscraft.core.telemetry. No extra heavy runtime deps beyond dscraft.core
itself — install via the security extra.
dscraft.agent
A minimal, real bring-your-own-agent benchmark loop: SandboxedAgentAdapter
always executes an agent's chosen action through a caller-supplied
dscraft.core.sandbox.BaseSandboxExecutor; a small file-manipulation task
family (pass-designed and sandbox-escape-attempt variants) proves the
sandbox genuinely drives the scored outcome; a tiny benchmark runner
reports aggregate pass rate and latency via dscraft.core.telemetry. No
extra heavy runtime deps beyond dscraft.core itself — install via the
agent extra.
dscraft.eda
LazyEDA is the single entry point over four independently-built pieces:
a lazy-Polars profiling engine (schema + per-column null counts + row
count, computed without materializing a source's full data), sketches
(HyperLogLog cardinality and KLL quantile estimation, via the Apache
Software Foundation's datasketches library), associations (a mixed
continuous/categorical/mixed-type pairwise correlation/association-matrix
suite built on SciPy), and a report renderer that turns already-
aggregated summaries into one self-contained, offline-friendly HTML/Canvas
document — no external CDN references, no charting library, just inlined
CSS/JS.
from dscraft.eda import LazyEDA
profile = LazyEDA().profile("orders.parquet")
print(profile.null_report.columns_with_nulls())
print(profile.association_matrix.columns)
profile.export("orders_eda_report.html")
LazyEDA.profile routes each column by the coarse category
engine.profile_schema already assigns it: "numeric" columns get a KLL
quantile pass (min/p25/p50/p75/max by default) plus an equal-width
histogram; "string" columns get an HLL cardinality estimate plus a
top-K value-frequency histogram; "boolean"/"temporal"/"other"
columns get neither sketch (see the module docstring in
dscraft/eda/__init__.py for the full rationale). The returned
EDAProfile exposes every intermediate result — the schema/null reports,
the per-column KLLResult/HLLResult sketches, and the
AssociationMatrixResult — as inspectable attributes, not just an
.export() side effect, matching this platform's convention (see
dscraft.clean's SanitizerReport) of returning programmatically usable
result objects. Outlier/anomaly detection and time-series-specific EDA
(despite dscraft.forecast being an obvious future consumer) are out of
scope for this pass — see DSCraft_Unified_Architecture.md's LazyEDA
module entry for what's deferred. Install via the eda extra.
For publication-quality, static, layered exploratory plots (as an
alternative to — not a replacement for — the interactive single-file HTML
report above), dscraft.eda.plots exposes association_heatmap and
column_distribution, which turn an AssociationMatrixResult or a
ColumnSummary you already have (e.g. from profile.association_matrix
or profile.report_data.column_summaries) into a plotnine.ggplot
object you can further customize and .save(path) yourself:
from dscraft.eda import LazyEDA, association_heatmap, column_distribution
profile = LazyEDA().profile("orders.parquet")
association_heatmap(profile.association_matrix).save("associations.png")
summaries = {s.name: s for s in profile.report_data.column_summaries}
column_distribution(summaries["amount"]).save("amount_distribution.png")
This is an optional, separately-gated capability: install the eda-plotnine
extra (pip install "dscraft[eda,eda-plotnine]") to use it — the base eda
extra alone does not pull in plotnine/matplotlib.
Examples
Every subpackage's packages/dscraft/examples/<subpackage>/ directory has
a plain runnable .py script plus a quickstart.ipynb Jupyter notebook
covering the same end-to-end scenario in cell-by-cell, explorable form —
both import the real installed package rather than reimplementing any
logic inline. Each notebook is scoped to install and run inside its own
subpackage's extra only (e.g. pip install -e "packages/dscraft[forecast,dev]" nbconvert ipykernel for forecast/quickstart.ipynb), matching this
package's per-subpackage extras design rather than one shared environment
with every extra installed at once:
| Subpackage | Notebook |
|---|---|
dscraft.automl |
examples/automl/quickstart.ipynb |
dscraft.clean |
examples/clean/quickstart.ipynb |
dscraft.forecast |
examples/forecast/quickstart.ipynb |
dscraft.graph |
examples/graph/quickstart.ipynb |
dscraft.vision |
examples/vision/quickstart.ipynb |
dscraft.tune |
examples/tune/quickstart.ipynb |
dscraft.security |
examples/security/quickstart.ipynb |
dscraft.agent |
examples/agent/quickstart.ipynb |
dscraft.eda |
examples/eda/quickstart.ipynb |
These notebooks are not currently executed by CI (the existing
examples-syntax job only py_compiles the .py scripts) — that's a
conscious, documented gap here, not an oversight; adding an
nbconvert --execute smoke-test job is a separate follow-up.
Further reading
See DSCraft_Unified_Architecture.md at the repo root for the full
locked v1 architecture — module scope, algorithms, licensing policy, and
what's deferred to later phases. Each subpackage's own docstrings and
packages/dscraft/tests/<subpackage>/ cover implementation-level detail
this README intentionally omits.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dscraft-0.2.0.tar.gz.
File metadata
- Download URL: dscraft-0.2.0.tar.gz
- Upload date:
- Size: 381.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1e08c740d654a148b4d1f1d6e9caf45ff23912cfa8811025b7b8a70edb75c70c
|
|
| MD5 |
e6bff7230c7318c3281cfd03fafe8fcf
|
|
| BLAKE2b-256 |
1fd1e9cf1c0da5fd80841aab9cca1432bdb85acce20d234a938c04bf20e31be0
|
Provenance
The following attestation bundles were made for dscraft-0.2.0.tar.gz:
Publisher:
publish.yml on gr3enarr0w/dscraft
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dscraft-0.2.0.tar.gz -
Subject digest:
1e08c740d654a148b4d1f1d6e9caf45ff23912cfa8811025b7b8a70edb75c70c - Sigstore transparency entry: 2214006450
- Sigstore integration time:
-
Permalink:
gr3enarr0w/dscraft@58fd5a27df6388269bf2a5a3de45a917d36bb5b6 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/gr3enarr0w
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@58fd5a27df6388269bf2a5a3de45a917d36bb5b6 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dscraft-0.2.0-py3-none-any.whl.
File metadata
- Download URL: dscraft-0.2.0-py3-none-any.whl
- Upload date:
- Size: 246.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca6cc02fed2344ef1eeb114c63867bebc4be538a6e79cbb10b9cb8d800156ddb
|
|
| MD5 |
1934008bc136e0fc9d7f605d051e7fa3
|
|
| BLAKE2b-256 |
444c5e00e189bfd6027d2e163b30fa6c121b1292fc633f6ee011858c1529d311
|
Provenance
The following attestation bundles were made for dscraft-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on gr3enarr0w/dscraft
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dscraft-0.2.0-py3-none-any.whl -
Subject digest:
ca6cc02fed2344ef1eeb114c63867bebc4be538a6e79cbb10b9cb8d800156ddb - Sigstore transparency entry: 2214006538
- Sigstore integration time:
-
Permalink:
gr3enarr0w/dscraft@58fd5a27df6388269bf2a5a3de45a917d36bb5b6 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/gr3enarr0w
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@58fd5a27df6388269bf2a5a3de45a917d36bb5b6 -
Trigger Event:
push
-
Statement type: