Skip to main content

Explain.io FinOps Airflow Cost Agent

Project description

๐Ÿ’ธ Explain.io โ€” Airflow Cost Agent

PyPI Beta Python Airflow

Explain.io is a FinOps tool for Data Engineers. This lightweight Airflow plugin automatically attributes Google Cloud BigQuery compute costs to the exact DAG and Task that triggered them.

No more guessing which pipeline caused the bill spike. No code changes required.

โœจ Features

  • Zero Code Changes โ€” Uses Airflow's Listener interface to automatically intercept all BigQuery task completions. You don't need to modify any DAG or add any callbacks.
  • Zero Blast Radius โ€” All network requests run asynchronously in a separate thread with strict timeouts. If the Explain.io API is unreachable, your DAG will still succeed. Exceptions are silently caught and logged.
  • Instant Dashboard โ€” View your pipeline costs, projected monthly spend, and heaviest DAGs at explain.io.

๐Ÿ” How It Works

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Airflow      โ”‚     โ”‚  Explain.io Agent    โ”‚     โ”‚  Explain.io API  โ”‚
โ”‚  (Scheduler)  โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚  (Listener Plugin)   โ”‚โ”€โ”€โ”€โ”€โ–ถโ”‚  (Backend)       โ”‚
โ”‚               โ”‚     โ”‚                     โ”‚     โ”‚                  โ”‚
โ”‚  Task succeedsโ”‚     โ”‚  1. Intercepts event โ”‚     โ”‚  Fetches BQ cost โ”‚
โ”‚               โ”‚     โ”‚  2. Extracts job ID  โ”‚     โ”‚  from GCP API    โ”‚
โ”‚               โ”‚     โ”‚  3. POSTs to API     โ”‚     โ”‚  and stores it   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The agent registers as an Airflow Listener plugin. On every task success, it checks if the task was a BigQuery operator, extracts the job ID via XCom, and sends it to the Explain.io API โ€” all in a background thread.


๐Ÿš€ Installation

Quick Start (Any Environment)

pip install explainio-airflow-agent

Then configure your API Key in Airflow. You can use either Airflow Variables (recommended, easiest) or Environment Variables:

Variable Required Description
EXPLAIN_IO_API_KEY โœ… Your API key. Set via Airflow UI (Admin โ†’ Variables) OR Environment Variable.
EXPLAIN_IO_API_URL โŒ API endpoint. Defaults to https://api.explain.io/api/v1/ingest

Verify it's working:

airflow plugins

You should see cost_agent_plugin in the output.


๐Ÿ“ฆ Installation by Platform

Self-Hosted: Docker (Recommended)

Don't use _PIP_ADDITIONAL_REQUIREMENTS โ€” it reinstalls packages on every container start and is only meant for quick testing.

Extend the official Airflow image with a Dockerfile:

FROM apache/airflow:3.1.6

USER airflow
RUN pip install --no-cache-dir explainio-airflow-agent

Then in your docker-compose.yaml, replace image: with build::

x-airflow-common:
  &airflow-common
  build: ./airflow          # instead of: image: apache/airflow:3.1.6
  environment:
    EXPLAIN_IO_API_KEY: ${EXPLAIN_IO_API_KEY}
    EXPLAIN_IO_API_URL: ${EXPLAIN_IO_API_URL}
    # ... other env vars

Build and start:

docker compose build
docker compose up -d

Important: All Airflow components (scheduler, webserver, workers, triggerer) must use the same image. The shared x-airflow-common anchor ensures this automatically.


Self-Hosted: Bare Metal / virtualenv

Install directly into the Python environment where Airflow runs:

pip install explainio-airflow-agent

Set the environment variables:

export EXPLAIN_IO_API_KEY="your-api-key"
export EXPLAIN_IO_API_URL="https://api.explain.io/api/v1/ingest"  # optional

If you run a multi-node setup (e.g., separate scheduler and workers), the package must be installed on every node.


AWS MWAA (Managed Workflows for Apache Airflow)

  1. Create or update your requirements.txt with the Airflow constraints file:

    --constraint "https://raw.githubusercontent.com/apache/airflow/constraints-2.10.1/constraints-3.11.txt"
    explainio-airflow-agent==0.1.2
    

    Adjust the constraints URL to match your MWAA Airflow version and Python version. See MWAA docs.

  2. Upload requirements.txt to your MWAA environment's S3 bucket.

  3. In the AWS Console โ†’ MWAA โ†’ your environment โ†’ Edit โ†’ point to the new requirements.txt path โ†’ Save.

  4. Set EXPLAIN_IO_API_KEY and (optionally) EXPLAIN_IO_API_URL under Environment variables โ†’ Airflow configuration options, using the prefix AIRFLOW__:

    • Key: EXPLAIN_IO_API_KEY, Value: your-api-key
  5. Wait for the environment update to complete (can take 20โ€“40 minutes).

Troubleshooting: Check CloudWatch Logs โ†’ Log group: airflow-{env-name}-requirements_install for pip errors.


Google Cloud Composer

Option A โ€” Console UI

  1. Go to Environments โ†’ click your environment โ†’ PyPI Packages tab.
  2. Click Edit โ†’ Add Package.
  3. Enter:
    • Package name: explainio-airflow-agent
    • Version: >=0.1.2
  4. Save. Composer will restart workers and the scheduler.

Option B โ€” gcloud CLI

gcloud composer environments update YOUR_ENV_NAME \
    --location YOUR_LOCATION \
    --update-pypi-package "explainio-airflow-agent>=0.1.2"

Environment variables

Set via the Console UI (Environment Variables tab) or CLI:

gcloud composer environments update YOUR_ENV_NAME \
    --location YOUR_LOCATION \
    --update-env-variables EXPLAIN_IO_API_KEY=your-api-key

Astronomer (Astro CLI)

  1. Add the package to requirements.txt in your Astro project root:

    explainio-airflow-agent==0.1.2
    
  2. Set environment variables in your .env file:

    EXPLAIN_IO_API_KEY=your-api-key
    
  3. Restart:

    astro dev restart
    
  4. Verify:

    astro dev bash --scheduler "airflow plugins"
    

For Astro Cloud deployments, add the environment variables via the Astro UI under Deployments โ†’ Environment Variables.


โš™๏ธ Configuration Reference

Variable Required Default Description
EXPLAIN_IO_API_KEY โœ… โ€” Your Explain.io API key. If not set, the plugin logs an info message and becomes a no-op.
EXPLAIN_IO_API_URL โŒ https://api.explain.io/api/v1/ingest Override the API endpoint (e.g., for self-hosted backends).

๐Ÿ”ง Troubleshooting

Plugin not showing in airflow plugins

  • Make sure the package is installed in the same Python environment as Airflow.
  • Run pip show explainio-airflow-agent to confirm it's installed.
  • Check Airflow scheduler logs for import errors.

Events not appearing in the dashboard

  • Confirm EXPLAIN_IO_API_KEY is set. Without it, the agent silently disables itself.
  • Check that EXPLAIN_IO_API_URL points to a reachable endpoint.
  • Look for [ExplainIO] log lines in the Airflow task logs.

AWS MWAA: Package fails to install

  • Ensure the --constraint line in requirements.txt matches your MWAA Airflow + Python version.
  • Check the requirements_install log stream in CloudWatch.

Supported Workloads

Explain.io perfectly isolates and captures BigQuery costs for the following workloads:

  1. Native Airflow Operators (e.g., BigQueryInsertJobOperator): Works instantly out-of-the-box.
  2. dbt-core (via BashOperator, KubernetesPodOperator, or Cosmos): Requires a 1-line configuration in your profiles.yml (see below).
  3. Custom Scripts (e.g., raw Python/Bash): Supported if you manually inject the airflow_dag_id and airflow_task_id labels into your BigQuery job configuration.

dbt Support (Required Configuration)

Because dbt runs externally and does not natively report BigQuery job IDs back to Airflow, Explain.io requires you to configure dbt to pass context labels to BigQuery to guarantee 100% accurate cost attribution.

1. Configure dbt Labels

To prevent cost collisions when multiple DAGs run concurrently, inject the Airflow context variables into your BigQuery jobs by adding this to your profiles.yml:

# profiles.yml
my_bigquery_profile:
  target: dev
  outputs:
    dev:
      type: bigquery
      # ... other config ...
      labels:
        airflow_dag_id: "{{ env_var('AIRFLOW_CTX_DAG_ID', '') }}"
        airflow_task_id: "{{ env_var('AIRFLOW_CTX_TASK_ID', '') }}"

Explain.io perfectly isolates the costs to the correct DAG using these labels. If you skip this step, Explain.io will not be able to track your dbt costs.

2. Enable Per-Model Attribution (Optional)

For per-dbt-model cost breakdowns, add job labeling to your dbt_project.yml:

# dbt_project.yml
query-comment:
  comment: "{{ query_comment(node) }}"
  job-label: true

This tells dbt to label every BigQuery job with the model name (node_id). Explain.io reads these labels to show you exactly which dbt models are costing the most.

GCP Permissions

Your dedicated Explain.io service account needs the following roles:

  1. BigQuery Resource Viewer (roles/bigquery.resourceViewer): To read BigQuery job metadata and labels (bigquery.jobs.listAll).

Security Note: Explain.io only requires metadata permissions. We cannot read your actual table data.

Grant it via:

gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
  --member="serviceAccount:YOUR_SA@YOUR_PROJECT.iam.gserviceaccount.com" \
  --role="roles/bigquery.resourceViewer"

๐Ÿ“„ License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

explainio_airflow_agent-0.2.4.tar.gz (11.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

explainio_airflow_agent-0.2.4-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

Details for the file explainio_airflow_agent-0.2.4.tar.gz.

File metadata

  • Download URL: explainio_airflow_agent-0.2.4.tar.gz
  • Upload date:
  • Size: 11.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for explainio_airflow_agent-0.2.4.tar.gz
Algorithm Hash digest
SHA256 042863080f60ccf8a957e36c6a9568c1b5ea80c29692849c6a1bf7eabf8bea23
MD5 35de5ec01904a448a4df0fa0076f7cc2
BLAKE2b-256 76ec540aea3cd7e339a6d9c4afbf11da690a61f236b594c8a8098ec70f9568b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for explainio_airflow_agent-0.2.4.tar.gz:

Publisher: publish-pypi.yml on eskarimov/Explain.io

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file explainio_airflow_agent-0.2.4-py3-none-any.whl.

File metadata

File hashes

Hashes for explainio_airflow_agent-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 425fcb6bf0a554fe765e7dc806fc77d9cbd5293f88643810f193b6d05f3c6929
MD5 7cf5b8ebfbf648b97eb32bce924d9477
BLAKE2b-256 f272f88aad33403b6ff253191d8ce99ec9d6da0b732f5ab9d54a68211354766c

See more details on using hashes here.

Provenance

The following attestation bundles were made for explainio_airflow_agent-0.2.4-py3-none-any.whl:

Publisher: publish-pypi.yml on eskarimov/Explain.io

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page