Skip to content

Integrations

Kanoniv integrates with the tools your data team already uses. The Python SDK provides source adapters for reading data and standard output formats for writing results to any destination.

Data Sources

CSV Files

Read customer data directly from CSV files — no database or warehouse required.

python
from kanoniv import Source

source = Source.from_csv("crm", "contacts.csv")

Best for: local development, prototyping, small datasets, CI/CD testing.

Pandas DataFrames

Pass any DataFrame to Kanoniv. Use this when your data comes from a custom pipeline, API response, or in-memory transformation.

python
import pandas as pd
from kanoniv import Source

df = pd.read_csv("contacts.csv")
# Or: df = pd.read_sql("SELECT * FROM customers", conn)
# Or: df = pd.read_parquet("customers.parquet")

source = Source.from_pandas("crm", df)

Best for: existing Python pipelines, data transformations, notebook workflows.

SQL Databases (via SQLAlchemy)

Connect to any SQL database — PostgreSQL, Snowflake, BigQuery, Redshift, MySQL — using Source.from_warehouse(). It uses SQLAlchemy under the hood, so any database with a SQLAlchemy dialect works.

python
from kanoniv import Source

# PostgreSQL
source = Source.from_warehouse(
    "crm", "public.customers",
    connection_string="postgresql://user:pass@host:5432/db",
)

Best for: production databases, data warehouses, direct warehouse queries.

Snowflake

Install the Snowflake SQLAlchemy dialect (pip install snowflake-sqlalchemy), then use from_warehouse():

python
from kanoniv import Source

source = Source.from_warehouse(
    "crm", "ANALYTICS.PUBLIC.CUSTOMERS",
    connection_string="snowflake://user:pass@account/ANALYTICS",
)

BigQuery

Install the BigQuery SQLAlchemy dialect (pip install sqlalchemy-bigquery):

python
from kanoniv import Source

source = Source.from_warehouse(
    "crm", "project.dataset.customers",
    connection_string="bigquery://project-id/dataset",
)

dbt Models

Read data from dbt models. Kanoniv resolves the model reference through the manifest to the underlying warehouse table.

python
from kanoniv import Source

source = Source.from_dbt(
    "crm", model="stg_customers",
    connection_string="snowflake://user:pass@account/ANALYTICS",
)

Resolves the model name via manifest.json to database.schema.alias, then reads from the warehouse using SQLAlchemy.

Best for: teams already using dbt for data transformation who want identity resolution as a downstream step.

Orchestration

Airflow

Run Kanoniv reconciliation as an Airflow task:

python
from airflow import DAG
from airflow.operators.python import PythonOperator
from datetime import datetime

def run_reconciliation():
    from kanoniv import Spec, Source, reconcile, validate

    spec = Spec.from_file("/opt/airflow/dags/specs/customer-spec.yaml")
    validate(spec).raise_on_error()

    sources = [
        Source.from_csv("crm", "/data/crm_export.csv"),
        Source.from_csv("billing", "/data/stripe_export.csv"),
    ]
    result = reconcile(sources, spec)

    # Write golden records
    result.to_dataframe().to_csv("/data/golden_customers.csv", index=False)
    print(f"Golden records: {len(result.golden_records)}")

dag = DAG(
    "customer_reconciliation",
    schedule_interval="@daily",
    start_date=datetime(2026, 1, 1),
)

reconcile_task = PythonOperator(
    task_id="reconcile",
    python_callable=run_reconciliation,
    dag=dag,
)

Prefect

python
from prefect import flow, task
from kanoniv import Spec, Source, reconcile, validate

@task
def load_spec():
    spec = Spec.from_file("customer-spec.yaml")
    validate(spec).raise_on_error()
    return spec

@task
def run_reconciliation(spec):
    sources = [
        Source.from_csv("crm", "contacts.csv"),
        Source.from_csv("billing", "stripe.csv"),
    ]
    return reconcile(sources, spec)

@flow
def reconciliation_flow():
    spec = load_spec()
    result = run_reconciliation(spec)
    print(f"Golden records: {len(result.golden_records)}")

reconciliation_flow()

Dagster

python
from dagster import op, job, Out
from kanoniv import Spec, Source, reconcile, validate

@op
def load_and_reconcile():
    spec = Spec.from_file("customer-spec.yaml")
    validate(spec).raise_on_error()

    sources = [
        Source.from_csv("crm", "contacts.csv"),
        Source.from_csv("billing", "stripe.csv"),
    ]
    result = reconcile(sources, spec)
    return result.to_dataframe()

@job
def reconciliation_job():
    load_and_reconcile()

Output Destinations

Kanoniv outputs golden records as Pandas DataFrames, which you can write to any destination:

CSV

python
result.to_dataframe().to_csv("golden_customers.csv", index=False)

Parquet

python
result.to_dataframe().to_parquet("golden_customers.parquet")

PostgreSQL / MySQL

python
import sqlalchemy

engine = sqlalchemy.create_engine("postgresql://user:pass@host/db")
result.to_dataframe().to_sql(
    "golden_customers",
    engine,
    if_exists="replace",
    index=False
)

Snowflake

python
from sqlalchemy import create_engine

engine = create_engine("snowflake://user:pass@account/ANALYTICS/PUBLIC?warehouse=COMPUTE_WH")

result.to_dataframe().to_sql(
    "golden_customers",
    engine,
    if_exists="replace",
    index=False
)

BigQuery

python
result.to_dataframe().to_gbq(
    "project.dataset.golden_customers",
    if_exists="replace"
)

S3

python
import boto3
import io

csv_buffer = io.StringIO()
result.to_dataframe().to_csv(csv_buffer, index=False)

s3 = boto3.client("s3")
s3.put_object(
    Bucket="my-bucket",
    Key="golden_customers.csv",
    Body=csv_buffer.getvalue()
)

Notebooks

Kanoniv works in Jupyter notebooks, Google Colab, and VS Code notebooks:

python
# In a notebook cell
from kanoniv import Spec, Source, reconcile, validate

spec = Spec.from_file("customer-spec.yaml")
validate(spec).raise_on_error()

sources = [
    Source.from_csv("crm", "contacts.csv"),
    Source.from_csv("billing", "stripe.csv"),
]
result = reconcile(sources, spec)

# Display golden records as a table
result.to_dataframe().head(20)

CI/CD

Run spec validation and reconciliation in CI/CD pipelines to catch breaking changes before deployment:

GitHub Actions

yaml
# .github/workflows/validate-spec.yml
name: Validate Spec
on: [push, pull_request]
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - run: pip install kanoniv
      - run: |
          python -c "
          from kanoniv import Spec, validate
          spec = Spec.from_file('customer-spec.yaml')
          result = validate(spec)
          result.raise_on_error()
          print('Spec validation passed')
          "

Integration Matrix

IntegrationSource AdapterOutputOrchestration
CSVSource.from_csv()to_csv()
PandasSource.from_pandas()to_dataframe()
PostgreSQLSource.from_warehouse()to_sql()
SnowflakeSource.from_warehouse()to_sql()
BigQuerySource.from_warehouse()to_gbq()
dbtSource.from_dbt()dbt Core
AirflowVia Python adapterVia Python outputPythonOperator
PrefectVia Python adapterVia Python output@task / @flow
DagsterVia Python adapterVia Python output@op / @job
GitHub ActionsVia CLI/PythonWorkflow step
JupyterAny adapterto_dataframe()

The identity and delegation layer for AI agents.