Skip to content

Getting Started

Installation

pip install tollkeeper                # core only, zero deps
pip install "tollkeeper[polars]"       # + Polars DQ checks
pip install "tollkeeper[iceberg]"      # + PyIceberg backend
pip install "tollkeeper[sql]"          # + sqlglot lineage parser
pip install "tollkeeper[all]"          # everything

For Airflow integration:

pip install airflow-tollkeeper

Requires Python 3.11+.

Basic CSV example

Write-audit-publish with CsvBackend:

import shutil
from pathlib import Path

from tollkeeper import Tollkeeper, CsvBackend, NullCheck, RowCountCheck

backend = CsvBackend(staging_dir=Path("/tmp/tollkeeper"), publish_dir=Path("/data/output"))

(Tollkeeper(backend)
    .table("sales")
    .write(lambda ref: shutil.copy("upstream_output.csv", ref))
    .audit([NullCheck("id"), RowCountCheck(min_rows=100)])
    .publish())

If any check fails, the staged file is rolled back automatically. Production is never touched.

Context manager usage

with Tollkeeper(backend).table("sales") as session:
    session.write(lambda ref: shutil.copy("upstream_output.csv", ref))
    session.audit([NullCheck("id")])
    session.publish()
# Auto-rollback on exception or if publish() was never called

Signal store basics

Coordinate across pipelines by tracking table readiness:

from tollkeeper import Tollkeeper, SqliteSignalStore

signal_store = SqliteSignalStore("/tmp/signals.db")
tk = Tollkeeper(backend, signal_store=signal_store)

# A signal is emitted automatically after a successful audit + publish.
# Downstream pipelines can check readiness:
signal = signal_store.check("sales", {"ds": "2026-01-15"})

DbApiSignalStore works the same way over any DB-API 2.0 connection (Postgres, MySQL, etc.) instead of SQLite.

Next steps

See the API Reference for the full surface: backends, checks, signal stores, and the SQL lineage parser.