Skip to main content

leeghwater

Your dlt pipeline, the same on your laptop and in a Databricks job. One command to run it, its secrets from a secret scope, and the things Databricks asks for kept out of your code.

ci PyPI Python License: Apache-2.0

Early. It has run as a serverless job and from a laptop against a real workspace; what was tried and what was not is in Tried, and not yet.

leeghwater is a package your dlt project imports. Your sources stay ordinary dlt code. leeghwater gives the project a command line, and for each run it makes the dlt pipeline from what the run names: a local file on a laptop, the schema your bundle deployed in a job.

Why

A dlt pipeline on Databricks tends to run only on a cluster. Every change is a deploy and a wait, and the secrets are in one place on a laptop and another in a job. So nobody runs the pipeline locally, and finding a typo takes ten minutes. With leeghwater the same command runs the pipeline on a laptop into a local file and unchanged in a job, with its secrets from one place.

Quickstart

A project is two files and a line in pyproject.toml. This one needs no workspace: on a laptop a run loads into a local DuckDB file.

uv init --package my-ingest && cd my-ingest
uv add leeghwater "dlt[duckdb]"

The app, which is the project's console script:

# src/my_ingest/cli.py
from leeghwater import App

app = App(pipelines="my_ingest.pipelines")
# pyproject.toml: in place of the script `uv init` wrote
[project.scripts]
ingest = "my_ingest.cli:app"

And a pipeline: a function marked @pipeline, in the module the app names.

# src/my_ingest/pipelines.py
import dlt
import leeghwater
from leeghwater import pipeline


@dlt.resource
def numbers(upto: int):
    yield [{"n": n} for n in range(upto)]


@pipeline
def example(upto: int = 3):
    """Load a few numbers."""
    p = leeghwater.create_pipeline("example")
    return leeghwater.run(p, numbers(upto))
uv run ingest list                      # the pipelines and their parameters
uv run ingest run example --upto 5      # run one, into example.duckdb
uv run ingest doctor                    # what would be set up, checked, nothing run

The same ingest run example is the entry point of a Databricks job, where it loads into the schema the bundle deployed and reads its secrets from a secret scope.

The docs

How to use it is in the docs, and only there:

Tried, and not yet

On 2026-10-07 a project ran as a serverless job on a workspace, and from a laptop with a profile: the bundle, the secrets from a scope, a pipeline that fails its task, and from the laptop a load into Unity Catalog. A full load from a serverless job, a notebook, a classic cluster and a real Azure Key Vault have not been tried.

Tried, and not yet is the record: what held, what did not, and why.

When not to use it

  • Lakeflow Connect has a connector for your source and it does what you need.
  • dlt runs somewhere else — Airflow, GitHub Actions — and only loads into Databricks. dlt does that alone.
  • The data needs Spark to move it. dlt is Python on one machine, and leeghwater doesn't change that.

leeghwater is a library for one kind of code, dlt ingestion. It will not:

  • deploy, schedule, or order one pipeline after another. That is a job's, and a bundle's;
  • add a file format for pipelines, or patch anything in dlt;
  • make, change or rotate secrets. That is the Databricks CLI's, and caland's;
  • change tables, or set table properties and clustering. dlt's own databricks_adapter does the second, in your source;
  • change anything on a cluster: no init script, no file outside the run's own directories.

When you no longer need it

When dlt reads Databricks secret scopes by itself and runs in a job with nothing around it — the right dlt imported, the bundle's schema names used as they are — use dlt alone. Today dlt has no provider for secret scopes, and its Databricks page gives workarounds for the import.

Where it fits

leeghwater is one of the Kostavo tools: small tools for the ugly gaps on Databricks, one gap each. Its gap is the pipeline that only runs on a cluster: every change a deploy and a wait, and the secrets in one place on a laptop and another in a job. Each works alone. Kostavo is the company behind them: it builds a governance platform for Databricks workspaces, and the tools are complete without it.

Community project, not affiliated with or endorsed by Databricks or dltHub.

Named after

Jan Adriaanszoon Leeghwater — the millwright who drained the Beemster with windmills, dry in 1612. He moved water from where it lay to where it was wanted.

License

Apache-2.0.

Metadata

Release files for leeghwater 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for leeghwater 0.2.0
File Size Uploaded
leeghwater-0.2.0.tar.gz 52.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for leeghwater 0.2.0
File Interpreter ABI Platform
leeghwater-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 89.0 kB

Release files / leeghwater-0.2.0.tar.gz

Download URL leeghwater-0.2.0.tar.gz
Size 52.1 kB
Tags Source
SHA-256 checksum
How to use checksums
4ee9e47edf4bcc952308588efbfe159aaf07d4770116d555105a677ae340d8ff
BLAKE2b-256 checksum
How to use checksums
01f7b4fceacfe5663d8f8ee1678af7bbe26b0f89eaa54097a808799ec46fdd9b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / leeghwater-0.2.0-py3-none-any.whl

Download URL leeghwater-0.2.0-py3-none-any.whl
Size 36.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d78a0c80a297093172e72953b4fd419329ed0008bc4b8ef53df6c6d5c9bf6c6b
BLAKE2b-256 checksum
How to use checksums
a80c463412af04c8c169b0bb302c1eb85c11ffd8a0b05354f211fa36c033f028
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.2.1

2 release files

This release

0.2.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page