Skip to main content

kq

CI PyPI Python versions License: MIT

KQL CLI — query Azure Data Explorer (Kusto) from the command line.

Like jq for JSON, but for Kusto/KQL. Run raw KQL, keep a git-versioned library of parameterized queries, and pipe results straight into your shell.

Installation

pip install kql-cli

The command you run is kq. The PyPI package is named kql-cli because kq was already taken on PyPI by an unrelated project.

Or from source:

git clone https://github.com/cptfinch/kq.git
cd kq
pip install -e .

Quick Start

# Configure your cluster
kq config set default_cluster https://mycluster.westeurope.kusto.windows.net
kq config set default_database mydb

# Authenticate
kq auth login

# Run queries
kq "MyTable | take 5"                    # Raw KQL
kq list                                   # List saved queries
kq run examples.sample MyTable 10         # Run saved query

Configuration

Config is stored in ~/.config/kq/config.yaml:

default_cluster: https://mycluster.westeurope.kusto.windows.net
default_database: mydb

clusters:
  prod:
    url: https://prod.westeurope.kusto.windows.net
    database: proddb
  dev:
    url: https://dev.westeurope.kusto.windows.net
    database: devdb

Configure via CLI:

kq config show                              # Show current config
kq config set default_cluster <url>         # Set default cluster
kq config set default_database <db>         # Set default database
kq config add-cluster prod <url> --database proddb  # Add named cluster

Commands

Command Description
kq auth login Authenticate to ADX
kq auth status Check authentication status
kq config show Show configuration
kq config set <key> <value> Set config value
kq list [category] List saved queries
kq show <query> Show query details
kq run <query> [params...] Run a saved query
kq "<kql>" Run raw KQL

Saved Queries

Queries are loaded from (in priority order):

  1. ./.kq/ - Project-local queries
  2. ~/.config/kq/queries/ - User queries
  3. Bundled examples

Query Format

Create YAML files in ~/.config/kq/queries/:

# ~/.config/kq/queries/myqueries.yaml
name: myqueries
description: My custom queries

queries:
  - name: recent
    description: Get recent records
    safety: safe
    parameters:
      - name: table
        description: Table name
        required: true
      - name: hours
        description: Hours to look back
        default: "24"
    query: |
      {table}
      | where Timestamp > ago({hours}h)
      | order by Timestamp desc
      | take 100
    example: "MyTable 24"

Then run:

kq list                        # Shows myqueries.recent
kq show myqueries.recent       # Show details
kq run myqueries.recent Events # Run with parameters

Output Formats

kq "MyTable | take 5" -f table    # Default - human readable
kq "MyTable | take 5" -f json     # JSON array
kq "MyTable | take 5" -f csv      # CSV

Authentication

Supports (in priority order):

  1. Service Principal - Set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID
  2. Azure CLI - Run az login first
  3. Device Code - Interactive browser login (tokens cached ~90 days)

Query Safety

Queries have a safety level:

  • safe - Queries with proper time/scope filtering
  • caution - May scan significant data, use carefully
  • dangerous - Can scan entire tables, requires explicit filtering

Always filter by time first:

// Good - filters first, cheap
MyTable | where Timestamp > ago(1d) | where Category == 'Error'

// Bad - scans everything, expensive
MyTable | where Category == 'Error'

Why kq?

  • LLM-native - Works seamlessly with Claude Code, Copilot, etc.
  • Portable - Same queries work across clusters
  • Versionable - Git-controlled query libraries
  • Unix-friendly - Pipes, scripts, automation
  • Personal queries - User queries never overwritten by updates

Development

git clone https://github.com/cptfinch/kq.git
cd kq
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"

pytest            # run tests
ruff check .      # lint
python -m build   # build sdist + wheel

CI runs lint + tests across Python 3.9–3.13 on every push and pull request.

Releasing

Releases publish to PyPI automatically via Trusted Publishing (OIDC — no tokens stored in the repo). To cut a release:

  1. Bump __version__ in src/kq/__init__.py and update CHANGELOG.md.
  2. Tag and push: git tag v1.2.3 && git push origin v1.2.3.

The release.yml workflow builds the artifacts and publishes them. This requires a one-time PyPI setup: configure kql-cli's trusted publisher to point at this repository, workflow release.yml, environment pypi.

License

MIT — see LICENSE.

Release files for kql-cli 1.0.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 kql-cli 1.0.0
File Size Uploaded
kql_cli-1.0.0.tar.gz 13.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for kql-cli 1.0.0
File Interpreter ABI Platform
kql_cli-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 29.1 kB

Release files / kql_cli-1.0.0.tar.gz

Download URL kql_cli-1.0.0.tar.gz
Size 13.6 kB
Tags Source
SHA-256 checksum
How to use checksums
d10512197779180dda37e7aaa902d57fa01412cc3d37f1e529602d0e6b49283a
BLAKE2b-256 checksum
How to use checksums
2e0d6f824d8d869ba44b3e66ab0ac9f045c15434806186d58052e74e4b1c80c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.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 Jul 22, 2026.

Transparency log

Release files / kql_cli-1.0.0-py3-none-any.whl

Download URL kql_cli-1.0.0-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6f69819dffe32fc5eb7a90f58bdfcc97533f418777f300027ee356745603f176
BLAKE2b-256 checksum
How to use checksums
3bf034623de526a6036fad8024fddba052913e1469d480ba58fe951d70c28d8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.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 Jul 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

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