Skip to content
v0.8.5 — live now

Stop trusting your pipeline. Verify it.

Draw it. Code it. Ship it. Skyulf keeps scikit-learn as the engine and adds what notebooks never gave you: reproducible artifacts, honest validation scores, and a path to production.

lock Self-hosted · Apache-2.0 library · your data stays on your machine

No signup and no install — the demo runs the real app in your browser. (Free instance, so the first load can take ~30s to wake.)

expand_more
built-in pipeline nodes
35
workspaces, EDA to audit log
11
skyulf-core, use it anywhere
Apache‑2.0
on scikit-learn, pandas & Polars
Python 3.12

One engine

Two ways to drive it.

Prefer clicking or typing? Both produce the same kind of pipeline, and the canvas exports to a notebook whenever you want to drop back into code.

account_tree

Skyulf Platform

Self-hosted workspace · AGPLv3

The full application: a node canvas, automated EDA, background training, experiment comparison, a model registry, deployment and monitoring, all running on your own machine or server.

  • check Drag, connect and configure 35 node types
  • check Training runs in the background while you keep working
  • check Export any pipeline to a runnable Jupyter notebook
Skyulf dashboard with jobs, deployments and success rate
Skyulf visual pipeline canvas with connected nodes
$ git clone https://github.com/flyingriverhorse/Skyulf
$ docker compose up
package_2

skyulf-core

Standalone Python library · Apache-2.0

No server, no UI, no lock-in. A pip-installable library that gives your scripts and notebooks one consistent pipeline API over scikit-learn, with the leakage checks and artifacts built in.

  • check Works standalone in any notebook or script
  • check Accepts pandas or Polars frames directly
  • check Permissive license, ship it inside your own product
See a runnable example expand_more
# Runs as-is: the dataset ships with scikit-learn.
from sklearn.datasets import load_breast_cancer
from skyulf import SkyulfPipeline

df = load_breast_cancer(as_frame=True).frame

# The pipeline is a dict, so you can version it, diff it in
# review, or build it in a loop.
pipeline = SkyulfPipeline({
    "preprocessing": [
        {"name": "split",  "transformer": "TrainTestSplitter"},
        {"name": "impute", "transformer": "SimpleImputer"},
        {"name": "scale",  "transformer": "StandardScaler"},
    ],
    "modeling": {"type": "random_forest_classifier"},
})

# Move the imputer above the splitter and it tells you so, by name.
print(pipeline.validate_leakage_safety())   # []

results = pipeline.fit(df, target_column="target")
print(results["modeling"]["splits"]["test"].metrics)
# {'roc_auc': 0.9954, 'f1': 0.9722, 'pr_auc': 0.9972, ...}

pipeline.save("tumour.pkl")  # one hash for data + steps + model

The path

From a raw file to a monitored model.

Every stage lives in one workspace, so nothing gets lost between a notebook, a spreadsheet of results and whatever is actually running in production.

Point it at a file and start working

Upload CSV, Excel, JSON or Parquet, or connect an S3-compatible bucket. Skyulf reads it with Polars, profiles the columns and keeps every version you load, so you can always tell which data produced which model.

Skyulf data sources screen listing uploaded datasets

Understand the data before you model it

One click profiles every column: distributions, correlations, outliers, interactions and clusters. Surrogate decision trees and causal discovery show which relationships actually drive your target.

EDA overview dashboard
Correlation matrix
Surrogate decision tree
Causal discovery graph

Design the pipeline instead of retyping it

Drag nodes onto the canvas and connect them. Branch a pipeline to try two feature strategies side by side, preview any node's output as a table, and let validation block a run before it wastes your time.

Skyulf visual pipeline canvas with connected nodes

Train in the background, tune when it matters

Runs execute as background jobs, so a long training run never freezes the UI. Switch on hyperparameter search — grid, random, halving or Optuna — and watch each trial report as it finishes.

Skyulf jobs list showing background training runs

Compare runs and pick a winner on evidence

Every run keeps its metrics, curves and confusion matrix. Put runs next to each other, see which change actually helped, and tune decision thresholds rather than accepting whatever 0.5 gives you.

Experiment comparison view with metrics and charts

Promote a version, serve predictions

Trained models land in a registry with their versions and artifacts. Promote one to active and it is served behind a REST endpoint you can call from anything. The full deployment history is kept for audit.

Deployments screen with the active model version and history

Find out before your users do

Models decay because the world moves. Skyulf compares live data against the training baseline column by column and flags what shifted — plus an error log, a slow-node profiler and an audit trail.

Drift monitoring dashboard
Detailed drift report per column
Error log with pipeline failures
Slow node profiling view

Your model says 94%. Production says 71%.

Usually nothing is broken. The score was just measured wrong, and nothing in a normal notebook tells you that.

The bug that doesn't raise an error

Fill missing values, scale a column or encode a category before you split into train and test, and those steps quietly learn from the test rows. Your validation score now includes answers it was supposed to be guessing. The code runs fine. The number just isn't real.

Skyulf checks the order of your pipeline and tells you in plain language, both on the canvas and in the library:

warning validate_leakage_safety()

Step 0 ('SimpleImputer') is configured before the train/test split (step 1, 'TrainTestSplitter') and will fit its statistics on the full dataset including the test set — move it after the splitter.

verified

Honest scores by construction

Every node is split into a part that learns and a part that applies. Learning only ever sees training data, and what it learned is saved as explicit parameters, so inference can never accidentally refit on new data.

fingerprint

Reproducible six months later

Each pipeline gets a fingerprint and an exportable model card. When someone asks which preprocessing produced a prediction, you answer with a record instead of a guess, and hand over a notebook that re-runs it.

vitals

Operations, not just training

Most visual ML tools stop at the model. Skyulf keeps going: drift reports, an error log that links to the failing node, slow-node profiling and an audit trail of every pipeline change.

vs. hand-written scikit-learn

Same estimators, none of the glue. You stop re-implementing split-transform-fit wiring for every project, and the ordering mistakes get caught for you.

vs. cloud AutoML

No upload, no per-prediction bill, no black box. You keep the data, you can read every step of the pipeline, and you can export it and walk away.

vs. other visual tools

The canvas isn't a dead end. It exports to a real notebook, and the same pipelines run from the Apache-2.0 library with no UI at all.

Everything else in the box

Shipped and documented, not on a roadmap.

inventory_2

Model registry

Versioned models with their artifacts and history, so you always know what is live.

tune

Hyperparameter tuning

Grid, random and halving search built in; Optuna available as an optional extra with live trial output.

insights

SHAP explanations

Optional explainability extra: see which features moved a prediction, globally or row by row.

menu_book

Notebook export

Turn any pipeline into a runnable Jupyter notebook, compact or full, including a serving snippet.

alt_route

Multi-branch pipelines

Split one canvas into independent paths and run them as parallel jobs to compare approaches.

layers

Ensembles

Voting and stacking for classification and regression, with nested tuning of the base models.

text_fields

Text & NLP nodes

TF-IDF, count and hashing vectorizers, tokenisation, and optional dense sentence embeddings.

public

Time-series & geo features

Lag and rolling windows, date parts, H3 indexing and distance features for spatial data.

receipt_long

Audit log

Every pipeline save recorded with what was added, removed or changed, and by whom.

Model registry listing models and versions
Audit log of pipeline changes

Claims are cheap. Here is the evidence.

Every number here comes from the repository, and the counts are yours to re-run.

fact_check

Tested where it matters

5,787 tests in total: 3,512 in the library, 1,427 in the backend and 848 in the canvas, plus browser tests that include an accessibility pass. Every pull request also runs lint, a type check, a JavaScript bundle-size budget and two Docker builds.

monitoring

Drift is measured four ways

A shifted column is caught with the Kolmogorov-Smirnov test, Population Stability Index, Wasserstein distance and KL divergence, each with its own threshold, instead of one number that either fires or does not.

rule

Say what your data must look like

Available expectations expect_columns_exist, expect_no_nulls, expect_value_range and expect_unique stop the run with a clear ExpectationError before a bad column reaches a model.

dashboard_customize

Start from a working pipeline

Five templates drop a wired graph onto the canvas: Tabular Classification, Tabular Regression, Text Classification, Customer Segmentation and Ensemble Classification. You adjust instead of assemble.

Questions, answered.

The questions people actually ask before trying it.

Powered by modern open source

Scikit-learnPandasFastAPIReactOptunaCeleryRedisPolarsNumPyImbalanced-learnSQLAlchemy

Ready to build?

Try the demo in your browser, or install the library and start from your next notebook.