Skip to main content

lkml-blastradius

The blast radius of every Looker change. Which dashboards, Looks, explores and Conversational Analytics agents a change hits, and how badly. It works in two ways:

  • On every push to a LookML repo, as a GitHub Action: what this commit would do to production content, checked in Looker development mode before it is deployed. The result is a job summary and one PR comment that is updated on each push.
  • Every morning: what actually changed in production (LookML deploys, Looker upgrades, Google releases) since yesterday.
pip install lkml-blastradius
lkblast init --push finance_project   # on-every-push workflow for one LookML repo
lkblast init                          # daily workflow + blastradius.yaml

Each run takes a metadata snapshot through the Looker API and compares it with the previous one:

It tracks From
Every explore and field: SQL, type, label, description, synonyms, joins, sql_table_name, always filters lookml_models, lookml_model_explore
Every dashboard tile and filter, Look, and merged query, with each field it uses (including filters, sorts, pivots, custom fields) dashboards, looks, queries, merge_queries
Conversational Analytics agents in Looker: explores, golden queries, fields named in instructions agents (beta API)
CA API data agents (optional) geminidataanalytics.googleapis.com dataAgents
Broken content, whatever the cause Looker content validator
Looker version and the deployed LookML commit of every project, including imported ones versions, projects/{id}/git_branch
What Google shipped Looker release-notes feed, CA API release notes

Then it reports what changed, old → new, which content it touches, how badly, and why:

Severity Meaning
Breaking A field, join or explore that the content uses was removed, or the content validator found a new error
Numbers may change SQL, type, measure filters, joins, table or always-filters changed for a field the content uses
AI agents may answer differently Descriptions, labels, synonyms, hidden flags or new fields changed in an explore an agent can use. Dashboards ignore these changes, but agents read them.
Cosmetic Labels or formats on dashboards and Looks

Every change is attributed to one of three causes: a LookML deploy in a named project (old → new commit), a Looker upgrade (old → new version) with no deploy, or neither. Changes from Google come from the upgrade line, the matching release notes, and the content validator.

Try it offline

lkblast demo    # two days on a fake Looker (fictional Harborline Supply Co.)
open lkblast-demo/reports/blastradius.html
  2 breaking, 3 numbers may change, 1 cosmetic
  2 new content error(s), 2 open
  Looker upgraded 26.14.2 → 26.16.1
  LookML deployed in core_project, finance_project
  3 new Google release note(s), 2 need attention
Content Severity Why Cause
Executive revenue / Revenue by region (tile) Breaking customers.region removed LookML deploy in finance_project
Executive revenue / Region (filter) Breaking customers.region removed LookML deploy in finance_project
Executive revenue / Net revenue by month Numbers may change orders.net_revenue SQL now also subtracts discounts LookML deploy in core_project (imported)
Collections / Amount due vs net revenue (merged query) Numbers may change same same
Finance assistant (Looker CA agent) Numbers may change its golden query uses orders.net_revenue same
Executive revenue / Order volume Cosmetic orders.order_count label same

The Refund watch Look and the Logistics helper agent are not listed because nothing they use changed.

On every push (for all teams)

Each team adds one workflow file to its LookML repo. lkblast init --push <project> writes it:

on:
  push:
    branches-ignore: ["lkblast-*"]   # lkblast's temporary branches (see below)
permissions: {contents: read, pull-requests: write}
concurrency: {group: lkml-blastradius-finance_project, cancel-in-progress: false}
jobs:
  blast-radius:
    runs-on: ${{ vars.LKBLAST_RUNS_ON || 'ubuntu-latest' }}
    steps:
      - uses: sangaraju1988/lkml-blastradius@v0
        with:
          project: finance_project
          looker-base-url: ${{ secrets.LOOKER_BASE_URL }}
          looker-client-id: ${{ secrets.LOOKER_CLIENT_ID }}
          looker-client-secret: ${{ secrets.LOOKER_CLIENT_SECRET }}
          fail-on: never        # or `breaking` to block merges that break production content

Set the three secrets once as organization secrets, and every team's workflow picks them up.

What one run does (lkblast check):

  1. Production: reads the project's explores, the dashboards, Looks and CA agents that use them, and the content validator errors.
  2. Development mode: creates a temporary branch lkblast-<sha> at the pushed commit in the API user's dev workspace. It reads the same explores as Looker compiles them there, so includes, extends, refinements and imports are all resolved by Looker itself, and runs the content validator against that LookML.
  3. Cleanup, always, even on failure: checks out the API user's original dev branch again, deletes the temporary branch (locally and on the remote), and switches the session back to production. The team's own branches are never checked out or reset.
  4. Report: the difference, mapped to production content, with the same severities as below. It goes to the job summary, an artifact (md/html/json) and one PR comment updated in place.

Things to know:

  • The API user needs develop on the project, plus see_lookml, see_user_dashboards and see_looks.
  • Temporary branches appear in your git remote for a few seconds, because Looker pushes branches it creates. The generated workflow ignores lkblast-* pushes, so they don't trigger it again. Other CI that runs on every branch should ignore them too.
  • Runs for one project are queued, not run in parallel (one API user has one dev checkout per project). The concurrency group handles this.
  • Projects without models (imported by others): pass the importing models with models:.

Action inputs: project, looker-base-url, looker-client-id, looker-client-secret, models, fail-on, content-validator, comment, slack-webhook-url, setup-python, ca-bundle, ref, label. Outputs: worst, report-dir. Try it offline with lkblast demo --push.

When GitHub can't reach Looker (internal Looker, private IP, Looker core in a VPC)

You don't need a network path from github.com into your network. A job runs on a runner, and a runner only makes outbound HTTPS connections to GitHub to pick up work. So put a runner where Looker is reachable:

Setup How
Self-hosted runner inside the network (most common) A VM or Kubernetes pod in the network or VPC that can reach Looker, registered to an organization runner group with a label such as looker. Set the org variable LKBLAST_RUNS_ON=looker, and every team's workflow runs there without editing the file. On GKE, Actions Runner Controller scales runners automatically.
Looker (Google Cloud core) with private IP / PSC Run that self-hosted runner in the same VPC, or in a VPC peered or connected to it.
GitHub-hosted larger runners with private networking (GitHub Enterprise Cloud) Azure private networking puts GitHub-hosted runners in your VNet. Alternatively, use static outbound IPs and allowlist them on a Looker that has an IP allowlist.
GitHub Enterprise Server (on-premises) Its runners are usually already inside the network. GITHUB_API_URL is honored for the PR comment.

On self-hosted runners:

  • setup-python: "false" uses the runner's own Python 3.11+, with no download from the internet.
  • HTTPS_PROXY / NO_PROXY are honored for Looker and GitHub calls. PIP_INDEX_URL points pip at an internal mirror.
  • ca-bundle: /path/to/corp-ca.pem (or SSL_CERT_FILE) handles a Looker with an internal certificate.

Run it daily (GitHub Actions + Slack)

  1. lkblast init in any repo (it can be an otherwise empty repo).
  2. Add repository secrets: LOOKER_BASE_URL, LOOKER_CLIENT_ID, LOOKER_CLIENT_SECRET, and optionally SLACK_WEBHOOK_URL.
  3. Push. The workflow runs at 06:00 UTC daily (change the cron in .github/workflows/lkml-blastradius.yml) or on demand from the Actions tab.

Every run writes reports/blastradius.{md,html,json}. The Markdown goes to the job summary, the reports are uploaded as an artifact, and a short summary with a link to the run is posted to Slack. Snapshot history lives in the Actions cache. Each run refreshes it, so it doesn't expire while the job runs daily.

The first run saves a baseline. Impact is reported from the second run on.

API user. Use API credentials of a user that can see all content (an admin, or a role with see_lookml, see_user_dashboards, see_looks, access_data on all models). Content the user can't see is not analyzed. Reading deployed commits needs see_lookml/develop; without it, the report still works but can't tell a LookML deploy from a Looker upgrade.

Options

blastradius.yaml (written by lkblast init; every key is optional):

looker:   {models: [], workers: 8, timeout_seconds: 120}
content:  {dashboards: true, looks: true, looker_agents: true, content_validator: true}
ca_api:   {enabled: false, locations: [global]}   # + GOOGLE_CLOUD_PROJECT, GOOGLE_OAUTH_ACCESS_TOKEN
releases: {enabled: true, lookback_days: 7}
storage:  {dir: .lkblast, keep: 30}
report:   {dir: reports}
lkblast run --fail-on breaking          # exit 1 when something breaks (for alerting)
lkblast compare OLD.json.gz NEW.json.gz # report between any two saved snapshots

To include CA API data agents, set ca_api.enabled: true and provide GOOGLE_CLOUD_PROJECT and an access token in GOOGLE_OAUTH_ACCESS_TOKEN. In Actions, get one with google-github-actions/auth (token_format: access_token). Agents that point at another Looker instance are ignored.

What it does not do

  • The daily mode reports changes after they reach production. Push mode checks LookML before deploy, but only the project you push (plus models:). Changes in other projects, or in content edited in the UI, show up in the daily report.
  • It never runs queries and stores no row data. It can't see a number change that comes from the warehouse data itself.
  • It can't see a Google change that alters behavior but not metadata, such as how an agent picks fields. That shows up only as an upgrade line and release notes. Agent answer regression testing is what lookml-agentops does.

API sources

Every Looker endpoint and attribute used is checked against Looker's OpenAPI spec (looker-open-source/sdk-codegen, spec/Looker.4.0.oas.json, 4.0.26.12). The list is in the docstring of looker.py. /agents is marked beta by Looker. CA API fields come from the v1 REST reference. Release-note formats were checked on 2026-10-03 (see releases.py). If Google changes the page layout, the run records a warning and continues.

Development

uv sync && uv run pytest && uv run ruff check src tests && uv run mypy

Apache-2.0. Not affiliated with or endorsed by Google. Looker is a trademark of Google LLC.

Metadata

Release files for lkml-blastradius 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 lkml-blastradius 0.2.0
File Size Uploaded Provenance
lkml_blastradius-0.2.0.tar.gz 90.0 kB With provenance Details

Built distribution (wheel)

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

Total release size: 144.2 kB

Release files / lkml_blastradius-0.2.0.tar.gz

Download URL lkml_blastradius-0.2.0.tar.gz
Size 90.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b193f8e1c3bfa01bbd5b0986efeb276aa17f75933795196ecfc16e8c3a62f551
BLAKE2b-256 checksum
How to use checksums
1c2ef391e46ec8c336e16045898e377fe94b0b583bd16afcc8d4a6c99cf84ba8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

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

Download URL lkml_blastradius-0.2.0-py3-none-any.whl
Size 54.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9a48571f97ef9fa1a2eb912921321c527366f69267d33faf4b8e39ce2a147f5c
BLAKE2b-256 checksum
How to use checksums
0280c316a8dc7255bfc06a1d6dd8aad3445ebe60f6111bb327e227fb1618c869
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Security for lkml-blastradius 0.2.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for lkml_blastradius-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

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.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

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