Ubunye Engine¶
Ubunye runs your data and ML jobs from a small folder of YAML and Python, the same way on a laptop, a cloud or Databricks.
- Write it once. A task is one folder: a
config.yamland atransformations.py. - Run it anywhere. pandas with no Java, or Spark on your laptop, a cluster, AWS, GCP, Azure or Databricks.
- Prove it's the same. Every run can leave a run record with a hash of every row, so two runs can be compared exactly.
Try it in 60 seconds¶
On pandas, so all you need is Python (which version): no Java, no cloud account.
pip install "ubunye-engine[pandas]"
ubunye init -d pipelines -u demo -p starter -t filter_adults
ubunye run -d pipelines -u demo -p starter -t filter_adults --backend pandas --lineage
ubunye lineage list -d pipelines -u demo -p starter -t filter_adults
init makes a task folder with eight sample people in a CSV. run keeps the
adults and writes them as Parquet. lineage list shows the run record the run left:
RUN_ID STARTED STATUS DUR ROWS
------------------------------------------------------------
a2da9fbd 2026-11-10T10:34:34 success 0.3s in:8 out:5
Next: the Quickstart explains each step, then runs the same folder on Spark.
What you get¶
The same task, unchanged, has given the same rows on pandas, local Spark, Kubernetes, AWS Glue, GCP Dataproc, Azure Container Apps and Databricks, checked from the run records by the proving ground (latest results).
New to the words below? Concepts explains use case, pipeline, task, profile, write mode, run record and backend in plain words.
- Config first. Inputs, outputs and Spark settings live in YAML, so no credentials or paths are hard coded. Config overview
- One config for every environment. A profile (
DEV,PROD) changes the Spark settings per environment, chosen with-m. Values can be filled in with Jinja2, a small template language:{{ dt }}becomes the run date. Profiles, Jinja - Connectors you declare, not code. Hive, JDBC, files on S3 or local disk, Delta, REST APIs, binary files and Unity Catalog (Databricks' catalog of tables). Connectors
- Backends. Run on Spark, Databricks, or pandas with no Java (
--backend).ubunye backendslists what each can do. Execution backends - Checks before a run.
ubunye validate(the config),ubunye plan(a dry run: what it will read and write) andubunye doctor(this machine). Which command catches what - Bad data stopped early. Expectations check inputs, put bad rows aside (quarantine) and reconcile input with output. Expectations
- Run records.
--lineagewrites one run record per run to.ubunye/lineage/: what ran, on what data, with a hash of every row.ubunye gateandubunye provecompare them. Run records - Safe reruns. A batch that was already appended is refused unless you pass
--rerun;--resumefinishes a pipeline that stopped half way. Safe reruns - Models. A library-independent
UbunyeModelcontract and a built-in registry to version, promote, roll back and gate models. Model contract, Registry - Observability. Prometheus, OpenTelemetry, MLflow and JSON event logs
through hooks (
ubunye.hooks), and export of run records to OpenLineage (an open standard for sharing what a job read and wrote). Hooks, OpenLineage - Orchestration export. One command writes an Airflow DAG, a Databricks job or a Spark Declarative Pipeline from the same config. Orchestration
- Deployment.
ubunye deployto Databricks, AWS Glue, GCP Dataproc, EMR Serverless, Kubernetes and Azure Container Apps. Deployment - Plugins. Add your own readers, writers, transforms and backends through
entry points (a standard Python way for an installed package to announce
plugins):
ubunye.readers,ubunye.writers,ubunye.transforms,ubunye.backendsand more.ubunye pluginslists what is installed. Writing your own - Agents.
ubunye mcpserves the engine over MCP (Model Context Protocol, the way AI agents call tools). It only reads unless you pass--allow-run. Agents over MCP - Tested three ways. A unit tier with no Java, a Spark tier, and a parity tier that checks Spark and pandas agree. Contributing
What Ubunye is not¶
- Not an agent framework. Use LangChain or CrewAI for that.
- Not an orchestrator. Use Airflow, Prefect or Dagster. (
ubunye exportwrites an Airflow DAG or a Databricks job for you.) - Not a compute engine. It runs on Spark, or on pandas for laptop-sized data.
Ubunye is the layer between your data sources and your applications that makes the plumbing the same everywhere, so you can focus on the logic.
Two ways to run a task¶
The Python API finds and reuses an active SparkSession on Databricks. When no
session exists, it creates one, the same as the CLI. Pass backend="pandas" to
run with no Spark at all.
A Spark example with profiles¶
This task reads a Hive table and writes Delta, so it needs the Spark backend (Spark on your machine, a cluster or Databricks). For a pandas example, see Try it in 60 seconds above.
# pipelines/fraud/etl/claims/config.yaml
MODEL: etl
VERSION: "1.0.0"
ENGINE:
profiles:
DEV:
spark_conf:
spark.sql.shuffle.partitions: "4"
PROD:
spark_conf:
spark.sql.shuffle.partitions: "200"
CONFIG:
inputs:
raw_claims:
format: hive
db_name: raw
tbl_name: claims
transform: {}
outputs:
clean_claims:
format: delta
path: s3://data-lake/clean/claims
mode: overwrite
ubunye plan -d pipelines -u fraud -p etl -t claims -m PROD # what it will read and write
ubunye run -d pipelines -u fraud -p etl -t claims -m PROD
-m PROD picks the PROD profile. Leave -m out and run uses DEV. Profile
names must match exactly, case included. Profiles
Documentation map¶
| Section | What's in it |
|---|---|
| Installation | Install, check it works, extras, Python and Java versions |
| Quickstart | Your first task, end to end, in 5 minutes |
| Concepts | The words the docs use, in plain language |
| Tutorials | Same result on pandas and Spark; a nine-table pipeline with data checks |
| Writing tasks | The full config.yaml reference |
| Connectors | Every built-in reader and writer |
| Machine learning | The UbunyeModel contract and the registry |
| Examples | Working examples, grouped by what you want to do |
| Deployment | Databricks, AWS, GCP, Azure, Kubernetes |
| How-to guides | Notebooks, RAG, drift, REST ingestion, hooks, gates and more |
| CLI reference | Every command and flag |
| Python API | run_task and run_pipeline |
| Execution backends | Spark, Databricks, pandas |
| Errors | Every error, what it means and what to do |
| Proving ground | One workload compared across environments |
| Developer guide | Architecture, plugins, testing |