Read-only BigQuery and Knowledge Catalog inspection CLI for AI agents
Project description
bq-inspector
bq-inspector is a read-only CLI for BigQuery: it fetches job metadata (jobs.get / jobs.list) and dataset or table metadata (datasets.get, tables.list, tables.get). It prints one JSON document on stdout on success. Errors are JSON on stderr with a non-zero exit code (except plain-text --help).
Operational commands take a single --params JSON object (or @path to a file). Field names match the command’s --input-schema output. For flags and options, bq-inspector --help and bq-inspector <command> --help are authoritative; this README may summarize and can lag behind the CLI.
This repository is the Python implementation (pip install bq-inspector, import name bq_inspector). The original TypeScript CLI and library live in the google-cloud-tools monorepo under packages/bq-inspect. Both implementations target the same agent-facing contracts (command names, --params shapes, error codes, and JSON Schema discovery).
Usage
bq-inspector <command> --params '<json>' | --params @file.json [options]
Every operational command also supports --input-schema and --output-schema (JSON Schema on stdout, no BigQuery call).
Install
From PyPI:
pip install bq-inspector
Or install as a standalone tool with uv:
uv tool install bq-inspector
From source (development or unreleased changes):
git clone https://github.com/yu-iskw/bq-inspector.git
cd bq-inspector
pip install .
# or: uv sync && uv run bq-inspector --help
Requires Application Default Credentials (ADC) unless you only use schema discovery flags (see below).
Help
bq-inspector --help
bq-inspector <command> --help
Use -h anywhere --help is accepted.
Unknown commands print global usage plus Unknown command: <argv>.
Agent workflow
- Discover the params shape:
bq-inspector <command> --input-schema(stdout is JSON Schema). - Build a JSON object with the required fields (camelCase keys such as
projectId,jobId,datasetId). - Run the command with inline JSON or a file.
Pipeline: jobs list → jobs summary | jobs query | jobs performance | jobs lineage | jobs impact | jobs get
Catalog / asset lineage: tables get → lineage links → lineage graph (Data Lineage API; see Lineage commands)
Knowledge Catalog (Dataplex): catalog search → catalog entries lookup → catalog aspect-types get (see Knowledge Catalog commands)
Command forms: Nested jobs summary and flat summary are equivalent for job views and jobs list → list.
Job id formats: Pass jobId alone, or a Console-style composite id in jobId:
"my-proj:US.bquxjob_abc" (location is parsed automatically; projectId must match if both are set).
Verifying lineage/impact: Use a job that references tables. Trivial queries like SELECT 1 legitimately return empty lineage/impact fields.
Smoke checklist: jobs list with allUsers: true → jobs summary and flat summary with composite or split job ref.
Which job command?
| Goal | Command |
|---|---|
| Find job ids (optional client-side filters) | jobs list |
| Status, timing, bytes/slots (default inspection) | jobs summary |
| SQL, configuration, and light lineage stats | jobs query |
| Query plan, timeline, performanceInsights | jobs performance |
| Tables, routines, datasets touched | jobs lineage |
| DML/load/ML/search/export side-effect stats | jobs impact |
| Full BigQuery Job resource | jobs get |
Asset lineage (table-centric, multi-hop via Data Lineage API):
| Goal | Command |
|---|---|
| Immediate upstream/downstream table neighbors | lineage links |
| Multi-hop lineage graph | lineage graph |
jobs lineage reports what a single job touched. lineage links / lineage graph query platform-wide table relationships (requires Data Lineage API enabled in GCP).
Knowledge Catalog (governed metadata via Dataplex API):
| Goal | Command |
|---|---|
| Discover catalog entries (keyword or semantic search) | catalog search |
| Resolve a discovered entry canonically | catalog entries lookup |
| Retrieve entry, type, or glossary resources | catalog entries get, catalog entry-types get, … |
| List entries, types, glossaries (one page per call) | catalog entries list, catalog glossaries list, … |
| Retrieve a known entry link | catalog entry-links get |
There is no catalog entry-links list command—the Dataplex API does not expose a general list method for entry links.
Each view command calls jobs.get once per job and projects the response in memory. jobs get returns the full Job resource from the API; other commands slice it for smaller, task-focused JSON. Field names match Job statistics; many nested blocks (for example statistics.mlStatistics) appear only for matching job kinds.
Shared / sandbox projects: jobs list returns your own jobs unless you set allUsers: true. In busy sandboxes, list with allUsers: true, then pass each job’s jobReference.location into job view commands. Omitting location on jobs.get often returns BQINSPECTOR_PERMISSION_DENIED (403), not a clear location error—the CLI hint will suggest adding location when that happens.
Example:
bq-inspector jobs summary --params '{"jobs":[{"projectId":"YOUR_PROJECT","jobId":"YOUR_JOB_ID"}]}'
bq-inspector summary --params '{"jobs":[{"projectId":"YOUR_PROJECT","jobId":"YOUR_PROJECT:US.bquxjob_abc"}]}'
Optional: bq-inspector <command> --output-schema for the response shape.
Invalid params fail with BQINSPECTOR_INPUT_INVALID and JSON Schema error paths on stderr; treat --input-schema as the contract for --params. See Error codes for other codes.
Quickstart
Inspect jobs
# Summary (default inspection — no SQL, no query plan)
bq-inspector jobs summary --params "$(cat <<'EOF'
{
"jobs": [{ "projectId": "YOUR_PROJECT", "jobId": "YOUR_JOB_ID" }]
}
EOF
)"
# Set location from jobs.list jobReference (required for non-default regions)
bq-inspector jobs summary --params '{"jobs":[{"projectId":"YOUR_PROJECT","jobId":"YOUR_JOB_ID","location":"asia-northeast1"}]}'
# Other job views: include location from jobs.list when jobs are regional (same shape as summary above)
bq-inspector jobs query --params '{"jobs":[{"projectId":"YOUR_PROJECT","jobId":"YOUR_JOB_ID","location":"asia-northeast1"}]}'
bq-inspector jobs performance --params '{"jobs":[{"projectId":"YOUR_PROJECT","jobId":"YOUR_JOB_ID","location":"asia-northeast1"}]}'
bq-inspector jobs lineage --params '{"jobs":[{"projectId":"YOUR_PROJECT","jobId":"YOUR_JOB_ID","location":"asia-northeast1"}]}'
bq-inspector jobs impact --params '{"jobs":[{"projectId":"YOUR_PROJECT","jobId":"YOUR_JOB_ID","location":"asia-northeast1"}]}'
bq-inspector jobs get --params '{"jobs":[{"projectId":"YOUR_PROJECT","jobId":"YOUR_JOB_ID","location":"asia-northeast1"}]}'
List jobs (jobs list)
Field list: Params reference (jobs list). Full schema: bq-inspector jobs list --input-schema.
In shared projects, set "allUsers": true or the list may be empty even when jobs exist. Use jobReference.location from list output for job view commands.
bq-inspector jobs list --params "$(cat <<'EOF'
{
"projectId": "YOUR_PROJECT",
"allUsers": true,
"minCreationTime": "2026-05-17T00:00:00Z",
"maxCreationTime": "2026-05-18T00:00:00Z",
"minSlotMs": "60000",
"labels": { "dbt_invocation_id": "abc123" },
"maxResults": 50
}
EOF
)"
Dataset and table metadata
bq-inspector datasets get --params '{"projectId":"YOUR_PROJECT","datasetId":"YOUR_DATASET"}'
bq-inspector tables list --params '{"projectId":"YOUR_PROJECT","datasetId":"YOUR_DATASET"}'
bq-inspector tables get --params '{"projectId":"YOUR_PROJECT","datasetId":"YOUR_DATASET","tableId":"YOUR_TABLE"}'
Asset lineage (lineage links, lineage graph)
Requires the Data Lineage API enabled and roles/datalineage.viewer on clientProjectId (defaults to projectId when omitted). The location param is the Lineage API location (us, eu, global, …), not the BigQuery dataset location.
# Immediate upstream sources (1 hop)
bq-inspector lineage links --params '{"location":"us","projectId":"YOUR_PROJECT","datasetId":"YOUR_DATASET","tableId":"YOUR_TABLE","direction":"UPSTREAM"}'
# Multi-hop downstream graph (default maxDepth 5)
bq-inspector lineage graph --params '{"location":"us","projectId":"YOUR_PROJECT","datasetId":"YOUR_DATASET","tableId":"YOUR_TABLE","direction":"DOWNSTREAM","maxDepth":10}'
Commands overview
| Command | What it returns (from help) | BigQuery APIs (typical) | Suggested predefined role |
|---|---|---|---|
jobs summary |
Job status, timing, bytes/slots (default inspection) | jobs.get |
roles/bigquery.resourceViewer |
jobs query |
SQL, configuration, light lineage stats | jobs.get |
roles/bigquery.resourceViewer |
jobs performance |
Query plan, timeline, performanceInsights | jobs.get |
roles/bigquery.resourceViewer |
jobs lineage |
Referenced tables, routines, datasets, destinations | jobs.get |
roles/bigquery.resourceViewer |
jobs impact |
DML/load/ML/search/export/spark side-effect stats | jobs.get |
roles/bigquery.resourceViewer |
jobs get |
Full BigQuery Job JSON | jobs.get |
roles/bigquery.resourceViewer |
jobs list |
List jobs (optional client-side filters in params) | jobs.list |
roles/bigquery.resourceViewer |
datasets get |
Dataset metadata | datasets.get |
roles/bigquery.metadataViewer (often granted on the dataset) |
tables list |
List tables in a dataset | tables.list |
roles/bigquery.metadataViewer |
tables get |
Table metadata | tables.get |
roles/bigquery.metadataViewer |
lineage links |
Immediate upstream/downstream table links | searchLinks |
roles/datalineage.viewer on clientProjectId |
lineage graph |
Multi-hop table lineage graph | searchLineageStreaming |
roles/datalineage.viewer on clientProjectId |
Project-wide datasets list is not supported (it would need datasets.list, which is outside the usual metadata-only posture).
Lineage commands
jobs lineage— job-local: tables/routines/datasets referenced by one BigQuery job (jobs.getprojection).lineage links— asset-centric: immediate neighbors via Data Lineage API (searchLinks).lineage graph— asset-centric: multi-hop graph via Data Lineage API (searchLineageStreaming).
Lineage commands use the cloud-platform OAuth scope (required by searchLinks; requested only when those commands run). Access is still constrained by IAM (roles/datalineage.viewer).
Params reference
Summaries from per-command --help; full types and constraints: bq-inspector <command> --input-schema.
All commands: optional impersonateServiceAccount, impersonateDelegates.
Job view commands (jobs summary, jobs query, jobs performance, jobs lineage, jobs impact, jobs get):
jobs: non-empty array of{ projectId, jobId, location? }— includelocationfromjobs.listoutput when jobs are not in the default region
jobs list:
projectId(required)- Forwarded to
jobs.list(API):minCreationTime,maxCreationTime,pageToken,maxResults,allUsers,state,parentJobId(allUsers: trueis often needed in shared sandboxes) - Post-list (current page only):
minSlotMs,minBytesBilled,labels— paginate withpageTokenif you need more matches. The Python port matches labels underconfiguration.labels(typical BigQuery shape); the TypeScript port only checks top-levellabels. - Regional jobs: read
jobReference.locationfrom list output; passlocationon job view commands, not onjobs list(BigQuery does not support a location query param onjobs.list)
Catalog (datasets get, tables list, tables get):
projectId,datasetId(tableIdrequired fortables get)tables listreturns all tables in the dataset (the SDK auto-paginatestables.list). Unlikejobs list, there is nopageTokenon this command.
Lineage (lineage links, lineage graph):
location(required) — Data Lineage API location (us,eu,global, …)projectId,datasetId,tableId(required) — table to search fromdirection(required) —UPSTREAMorDOWNSTREAMclientProjectId(optional) — API billing/quota project; defaults toprojectIdlineage linksonly:pageSize,pageTokenlineage graphonly:maxDepth(default 5),maxResults(default 1000)
Knowledge Catalog (catalog search, catalog entries lookup, …):
catalog search:projectId,query(required);locationdefaults toglobal; optionalscope,semanticSearch(defaultfalse),orderBy,pageSize(default 50),pageTokencatalog entries lookup:projectId,location,entry(required); optionalview,aspectTypes,paths- Get commands: canonical Dataplex
name(required); entries get also supportsview,aspectTypes,paths - List commands:
parent(required); optionalpageSize(default 100),pageToken,filter,orderBy - List and search commands return one upstream API page per invocation (no hidden auto-pagination)
JSON Schema discovery
- Discovery:
--input-schemaor--output-schema(use one at a time; prints JSON Schema on stdout and exits without calling BigQuery). - Required for runs:
--paramsas JSON or@pathto a JSON file.
Examples:
bq-inspector jobs summary --input-schema
bq-inspector jobs summary --output-schema
bq-inspector jobs get --input-schema
bq-inspector jobs list --input-schema
bq-inspector datasets get --output-schema
bq-inspector lineage links --input-schema
bq-inspector lineage graph --output-schema
bq-inspector catalog search --input-schema
bq-inspector catalog entries lookup --output-schema
Knowledge Catalog commands
Read-only Knowledge Catalog inspection via the Dataplex API. CLI command group: catalog. Internal package: knowledge_catalog.
bq-inspector catalog search --params '{"projectId":"YOUR_SEARCH_PROJECT","query":"YOUR_TERM","pageSize":50}'
bq-inspector catalog entries lookup --params @lookup.json
bq-inspector catalog entry-types list --params '{"parent":"projects/YOUR_PROJECT/locations/global","pageSize":5}'
bq-inspector catalog glossaries list --params '{"parent":"projects/YOUR_PROJECT/locations/YOUR_LOCATION","pageSize":5}'
IAM (least privilege):
- Search request project:
roles/dataplex.catalogViewer(includesdataplex.projects.search) - BigQuery-backed search results: also requires
roles/bigquery.metadataVieweron relevant datasets/projects - Impersonation:
roles/iam.serviceAccountTokenCreatoron the target service account
Catalog commands use OAuth scope https://www.googleapis.com/auth/cloud-platform (required by Dataplex Universal Catalog REST methods such as lookupEntry and searchEntries).
Empty search results are successful (not an error). They may indicate no matches, narrow scope, missing source-system metadata visibility, or VPC Service Controls boundaries.
Metadata sensitivity: catalog output may include schemas, descriptions, ownership, classifications, and glossary terms. Treat stdout as potentially sensitive in CI and agent environments.
Error codes
Errors are JSON on stderr with a code field. Schema validation failures include schemaErrors with JSON Pointer paths.
| Code | Typical cause |
|---|---|
BQINSPECTOR_INPUT_INVALID |
Bad --params or flags; schema validation; HTTP 4xx (except 401/403/404/429). |
BQINSPECTOR_PERMISSION_DENIED |
IAM or ADC; on jobs.get, often missing location or wrong job ref (see Troubleshooting). |
BQINSPECTOR_JOB_NOT_FOUND |
HTTP 404 from BigQuery (job or catalog). Read source.api and hint for the resource type. |
BQINSPECTOR_LOCATION_REQUIRED |
Reserved; prefer location on job refs (see hints on 403). |
BQINSPECTOR_API_RATE_LIMITED |
HTTP 429; retryable. |
BQINSPECTOR_API_UNAVAILABLE |
Transient API / 5xx. |
BQINSPECTOR_INTERNAL |
Unexpected CLI failure. |
Troubleshooting
Symptom-first checks when JSON looks wrong but the CLI is working:
jobs list returns "jobs": []
- In shared sandboxes, set
"allUsers": truein--params(default list is only your user’s jobs). - With impersonation: the caller needs Service Account Token Creator on the target; the impersonated identity needs BigQuery job list access (
roles/bigquery.resourceVieweror equivalent).
Job view commands return per-job BQINSPECTOR_PERMISSION_DENIED (403)
locationomitted: copyjobReference.locationfromjobs listinto each job ref (required for many regional jobs).locationset: BigQuery may still return 403 Access Denied for a wrongjobId, wrong region, or IAM—not only missinglocation. ConfirmprojectIdandjobIdfromjobs list; do not assume the code will beBQINSPECTOR_JOB_NOT_FOUND.
BQINSPECTOR_JOB_NOT_FOUND
- Typical for a wrong project on a job ref, a missing dataset or table, or catalog APIs returning HTTP 404.
- The error code matches the TypeScript port for all 404 responses. Use
source.api(bigquery.jobs.getvsbigquery.datasets.get, etc.) and the stderrhintto tell jobs from catalog resources apart.
Post-filters on jobs list (minSlotMs, minBytesBilled, labels)
- Applied to the current API page only. If results are empty, increase
maxResultsor followpageTokenuntil matches appear.
Multi-job --params
- The process can exit 0 while individual entries in
jobs[]includeerrors. Inspect each job element.
Authentication
The CLI uses the official BigQuery client with Application Default Credentials from google-auth.
- Default: credentials are scoped to
https://www.googleapis.com/auth/bigquery.readonlyfor BigQuery job and catalog commands. - Lineage commands (
lineage links,lineage graph) usehttps://www.googleapis.com/auth/cloud-platform(required by the Data LineagesearchLinksAPI; requested only when those commands run). - Knowledge Catalog commands (
catalog …) usehttps://www.googleapis.com/auth/cloud-platform(required by Dataplex Universal Catalog REST APIs). - Impersonation: set
impersonateServiceAccount(and optionalimpersonateDelegates) in--params. The source principal must have Service Account Token Creator on the target (and on each delegate). While impersonating, access is still requested withbigquery.readonlyon the target identity. The source ADC client useshttps://www.googleapis.com/auth/cloud-platformonly for the token exchange path.
Example params fragment:
{
"impersonateServiceAccount": "TARGET@PROJECT_ID.iam.gserviceaccount.com",
"impersonateDelegates": ["FIRST_DELEGATE@PROJECT_ID.iam.gserviceaccount.com"]
}
Service account JSON key files are not a dedicated CLI option; ADC may still resolve a key via environment if your platform configures it that way.
IAM guidance
Prefer narrow read access:
- Job commands /
jobs list:roles/bigquery.resourceViewer(or a custom role withbigquery.jobs.get/bigquery.jobs.list) on the identity that calls BigQuery (the impersonated service account when using impersonation). datasets get/tables list/tables get:roles/bigquery.metadataVieweron the dataset or project (or a custom metadata-only role withdatasets.get,tables.list,tables.get).lineage links/lineage graph:roles/datalineage.vieweronclientProjectId; enable the Data Lineage API in that project.catalog search:roles/dataplex.catalogVieweron the search request project; BigQuery-backed results also needroles/bigquery.metadataVieweron source datasets/projects.- Other
catalogcommands:roles/dataplex.catalogVieweron the relevant catalog resources. - Grant the calling principal
roles/iam.serviceAccountTokenCreatoron the target service account (and delegates, if any) when using impersonation. - Avoid
roles/bigquery.dataViewerandroles/bigquery.jobUserfor inspection-only workflows.
Programmatic use (Python)
The primary surface is the bq-inspector CLI. For in-process use, import from the bq_inspector package (for example core use cases under bq_inspector.core, ports under bq_inspector.bigquery.port, and JSON Schema helpers under bq_inspector.schemas). The package does not yet expose a stable public API beyond what the CLI uses internally; prefer subprocess invocation or the TypeScript library in google-cloud-tools if you need a documented library entrypoint today.
See CONTRIBUTING.md for architecture and test patterns when extending the Python implementation.
Security notes
Read-only metadata: job resources and dataset/table metadata only. No table row reads and no arbitrary query execution. Job output may include SQL, user emails, and other fields from the BigQuery API; the caller is responsible for where JSON is stored or logged.
Development
See CONTRIBUTING.md and AGENTS.md for setup, lint, and test commands.
make setup
make lint
make test
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bq_inspector-0.2.0.tar.gz.
File metadata
- Download URL: bq_inspector-0.2.0.tar.gz
- Upload date:
- Size: 207.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
786d34d754d17d2650be202c1d9f96b8c55998da1bb2abd38d34b86376ae324f
|
|
| MD5 |
84f4bbc35b44dc8bc58a41113a9c9268
|
|
| BLAKE2b-256 |
c5598c69a0cf2e06ae01d00dd6dc5e583aa6569d8d0f64f63c4aaa0cc784c1f9
|
File details
Details for the file bq_inspector-0.2.0-py3-none-any.whl.
File metadata
- Download URL: bq_inspector-0.2.0-py3-none-any.whl
- Upload date:
- Size: 110.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ddde4a2dd17cd5e5a37eb66d38e2a9de113e3457d280bcbbfd0df1fa03896ba9
|
|
| MD5 |
6b4bac3b9da4de646d952debbf2a4489
|
|
| BLAKE2b-256 |
39dfad1b803fa34b8dbc2851178da9f57f31a758b07e476f2ba74f401f7cf600
|