ETLai
A local, AI-assisted data transformation engine built on Dagster. Install it, scaffold a project, and let Claude Code create new pipelines — from CSV transformations to API ingestion.
Install
pip install ETLai
Requires Python 3.10+ and Tkinter (ships with most Python installations).
Quick start
etlai init ~/my-etl
cd ~/my-etl
# Option A: Create a pipeline with the 5-agent system
etlai create "join sales data with product catalog and compute revenue"
# Option B: Manual pipeline creation (see ARCHITECTURE.md)
etlai sync
etlai run
This starts a Dagster dev server at http://localhost:3000. Enable sensors in
the UI, then drop CSV files into pipelines/<name>/inbox/.
Commands
| Command | Purpose |
|---|---|
etlai init <dir> |
Scaffold project (templates, workflow, agents, example pipelines) |
etlai create "request" |
Create pipeline via 5-agent system with gate validation |
etlai sync |
Validate manifests, create folders, prompt path: ask, check env files |
etlai run |
Start Dagster dev server |
etlai list |
Show registered pipelines with atoms and min_files |
How it works
Each pipeline is defined by a manifest (pipelines/<name>/manifest.yaml)
that wires together:
- Atoms — reusable, single-unit-of-work transformations (domain-agnostic)
- Triggers — what causes the pipeline to run (file sensor, cron, or both)
- Config — business logic (column names, thresholds, expressions) in config.json
Trigger fires → load files → read config.json → execute steps
├→ processed/ + output/ (success)
└→ rejected/ + *.error.txt (failure)
Pipeline types
Single atom (file-based)
Drop files into inbox/. Sensor detects stable files and triggers the pipeline.
name: vlookup_rollnumber
atom: vlookup
min_files: 2
inputs_map:
- param: left_file
- param: right_file
Its parameters live in pipelines/vlookup_rollnumber/config.json.
API-based (data ingestion)
Fetch data from REST APIs on a schedule. No inbox files needed.
name: fetch_hr_data
atom: api_fetch
min_files: 0
env_file: ~/.etlai/secrets.env
requires_env: [HR_API_TOKEN]
trigger:
rules:
- type: schedule
cron: "0 8 * * *"
Composite (multi-step chains)
Chain multiple atoms with reference file injection and branching.
name: sales_reconciliation
min_files: 1
inputs:
- name: sales_data
role: transient
description: "Weekly sales CSV"
steps:
- atom: vlookup # step 0: join sales + catalog
inputs_map:
- param: left_file
- param: right_file
source: reference # permanent lookup matched by pattern
pattern: "catalog.csv"
- atom: computed_column # step 1: compute revenue
inputs_map:
- param: input_file
source: prev_output
- atom: group_aggregate # step 2: aggregate by category
input_from: 1 # reads step 1, not step 2 (branching)
inputs_map:
- param: input_file
source: prev_output
- atom: rename_columns # final step: rehydrate column names
inputs_map:
- param: input_file
source: prev_output
trigger:
rules:
- type: inbox_files
min_files: 1
Shipped atoms (10)
| Atom | Operation |
|---|---|
vlookup |
Left join two CSVs on a key column |
computed_column |
New column from expression (e.g. price * qty) |
group_aggregate |
Group + sum/mean/min/max/count aggregations |
filter_rows |
Keep rows matching a condition |
flag_rows |
Add boolean column from condition (keeps all rows) |
rename_columns |
Rename columns via mapping |
sort_rows |
Sort by one or more columns |
groupby |
Group by column with count |
api_fetch |
HTTP fetch → CSV (JSON/XML/CSV response parsing) |
mock_generate |
Generate synthetic data from CSV headers → single XLSX |
Creating pipelines with AI
The 5-agent system (etlai create) orchestrates pipeline creation through 7
phases with deterministic gate validators between each:
| Agent | Role |
|---|---|
| Orchestrator | Coordinates agents; owns user channel for BA mediation |
| Business Analyst | Worker: drafts requirements graph; proposes questions (no user session) |
| Separator | Strips domain terms, produces generic operation graph |
| Atom Smith | Matches/creates atoms (firewalled from business data) |
| Assembler | Wires manifest + config with real business values |
The firewall physically hides business_mapping.json from Atom Smith,
ensuring atoms remain domain-agnostic by construction.
See ARCHITECTURE.md for full details on the agent system.
Key concepts
reference (permanent lookup files)
Permanent lookup files in reference/ bind to a step param via source: reference:
steps:
- atom: vlookup
inputs_map:
- param: left_file
- param: right_file
source: reference
pattern: "catalog.csv"
input_from (non-linear step routing)
Steps read the previous step's output by default. Use input_from to branch:
steps:
- atom: computed_column # step 0
- atom: rename_columns # step 1 (reads step 0)
- atom: group_aggregate # step 2 reads step 0, NOT step 1
input_from: 0
config.json
Every step reads its step_N key (including step_0):
{
"step_0": {"left_column": "sku", "right_column": "sku"},
"step_1": {"expression": "price * qty", "output_column": "revenue"},
"step_2": {"mapping": {"revenue": "Total Revenue"}}
}
Credentials
API credentials live in env files outside the project (e.g. ~/.etlai/secrets.env).
etlai sync validates required vars are present without printing values.
Resolution order
- Atoms:
./atoms/<name>.py→etlai.atoms.<name>(package)
User atoms take precedence over shipped ones.
Development
git clone <repo>
pip install -e ".[dev]"
pytest --cov=etlai
See CONTRIBUTING.md for workflow, ARCHITECTURE.md for internals, and TESTS.md for testing guide.
Metadata
Release files for ETLai 0.6.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| etlai-0.6.2.tar.gz | 97.3 kB | Without provenance | Details for etlai-0.6.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| etlai-0.6.2-py3-none-any.whl | Python 3 | none | any | Details for etlai-0.6.2-py3-none-any.whl |
Total release size: 208.2 kB
Release files / etlai-0.6.2.tar.gz
| Download URL | etlai-0.6.2.tar.gz |
|---|---|
| Size | 97.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7b347f335118bbeade5f13cadf200f14e4062fd1abf1c7d7efb85ffe6013e07c
|
|
BLAKE2b-256 checksum How to use checksums |
4530285db80c8905b665fe9ab3a7b44bb7f64955437d3d28628f8f9439514f0d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|
Release files / etlai-0.6.2-py3-none-any.whl
| Download URL | etlai-0.6.2-py3-none-any.whl |
|---|---|
| Size | 111.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
42f108b545c3a14c00bb0ccbb928a0e793b4da9fe0ea35505135d443e56fa7d6
|
|
BLAKE2b-256 checksum How to use checksums |
845fa0905f05f1b4a23e73d8e279043ce79ea233d6ac6a6f93f87e584def69db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.5
|
Security for ETLai 0.6.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.