Skip to main content

duckdb-kql

CI PyPI Python versions

Run Kusto Query Language (KQL) queries on DuckDB in Python. Develop KQL queries locally, run them in unit tests, as part of CI builds, have AI agents verify their work, etc. without the need for network.

import duckdb_kql

con = duckdb_kql.connect()
con.sql("CREATE TABLE Logs AS SELECT * FROM 'logs.parquet'")

duckdb_kql.query(con, """
    Logs
    | where Timestamp > ago(1d) and Level == "Error"
    | summarize Count = count() by bin(Timestamp, 1h), Component
    | sort by Timestamp asc
""")

See the demo notebook.

Install

APIs are split into 3 layers to control features and dependencies. Select based on needs.

Layer Install Scenario Dependencies
0 pip install duckdb-kql Translate KQL queries to SQL antlr4 only
1 pip install duckdb-kql[duckdb] Run KQL queries adds duckdb
2 pip install duckdb-kql[kusto] Run KQL queries via Kusto SDK APIs adds pandas

See Getting started.

To reduce runtime dependencies, translate KQL queries to SQL at build time using the CLI.

duckdb-kql translate -o query.sql query.kql

See Build-time translation.

KustoClient query

Run queries using APIs compatible with Kusto client SDK (azure-kusto-data).

from duckdb_kql.kusto import KustoClient
from duckdb_kql.kusto.helpers import dataframe_from_result_table

client = KustoClient(con)

response = client.execute("NetDefaultDB", """
    Requests
    | where Status >= 500
    | summarize Errors = count() by Service
    | sort by Errors desc
""")

dataframe_from_result_table(table)

See Kusto client.

Local HTTP server

Start a local KQL HTTP server using the CLI.

duckdb-kql serve

Then open https://dataexplorer.azure.com, choose 'Add connection', and enter http://127.0.0.1:31415.

See Kusto server.

Query validation and translation

Use validate() and to_sql() to respectively validate the KQL query and translate it to SQL.

>>> duckdb_kql.to_sql("print x = 1 + 1")
'SELECT (CAST(1 AS BIGINT) + CAST(1 AS BIGINT)) AS "x"'

>>> duckdb_kql.validate("Logs | where Level ==")
[Diagnostic(span=SourceSpan(line=1, column=21), message="mismatched input '<EOF>' ...")]

Query parameters

Declare parameters and pass values to defend against query injections.

duckdb_kql.query(con, """
    declare query_parameters(state:string);
    StormEvents | where State == state
""", {"state": user_input})

Scripts

Run several commands at once using scripts. Blank lines separate the statements.

duckdb_kql.script(con, """
    .set-or-replace Errors <| Logs | where Level == "Error"

    .set-or-replace ByComponent <| Errors | summarize n = count() by Component
""")

Also available through the CLI.

duckdb-kql script schema.kql -d logs.duckdb

Cross-cluster queries

Map remote databases to local ones to run queries referencing cross-cluster tables.

duckdb_kql.set_clusters({
    ('cluster1.eastus.kusto.windows.net', 'Customers'): 'Customers',
    ('cluster2.westus.kusto.windows.net', 'Sales'): 'Sales',
})

duckdb_kql.query(con, '''
    cluster('cluster1.eastus.kusto.windows.net').database('Customers').Customers
    | join kind=leftouter (cluster('cluster2.westus.kusto.windows.net').database('Sales').Orders) on CustomerId
    | project-away CustomerId1
''')

Macro expansion and entity groups

Register entity groups to run queries calling macro-expand.

duckdb_kql.set_entity_groups({
    'MyDatabases': ["database('Customers')"]
})

duckdb_kql.query(con, '''
    macro-expand MyDatabases as db ( db.Customers | where Tier == 'Free' ) | count
''')

Coverage

Correctness measured against the real KQL engine (the Kusto Emulator).

Doc-corpus cases matching ground truth 285 of 1036 (0 mismatches)
Azure Monitor's published KQL subset 115 / 119 (96%)
Tabular operators 22 / 42
Scalar functions / aggregates / binary operators 111 / 19 / 33

Supported operators: where, project, project-away, project-rename, extend, summarize, join, mv-expand, distinct, count, sort / order by, top, take / limit, union, macro-expand, lookup, parse, parse-where, render; sources print, datatable, range, and tables; plus let and declare query_parameters.

The support matrix lists every operator, function and type, supported or not, with the known limitations and Kusto discrepancies for each.

Documentation

Document Topics
Getting started Install, first query, the three layers
KQL support matrix Every operator and function, supported or not, each with its gotchas
Build-time CLI Translating .kql to .sql in CI, to avoid a runtime dependency
Local Kusto endpoint duckdb-kql serve — query a DuckDB file from the Azure Data Explorer UI
API reference Every public function and type
Kusto SDK compatibility What Layer 2 implements, no-ops, and refuses
Azure Monitor profile Coverage against a published KQL subset
docs/TRANSLATION.md Normative KQL→DuckDB mapping spec (R1–R16)
docs/create-database.md Reference notes for .create database, reconstructed from the KQL parser
docs/implementation-plan.md Architecture and milestones
docs/test-plan.md Corpus harvesting, oracle, divergence catalog
docs/code-review/ Review framework: severity scale, reporting format, one checklist per area
docs/maintenance/ Maintenance framework: refactoring gate, technical debt, upgrades, and the metrics that measure them
docs/kql-on-duckdb-landscape.md Survey of existing KQL-on-DuckDB work
docs/implementation-options.md Six approaches considered, with the chosen one
docs/m0-grammar-spike.md Grammar viability result
docs/frequency-scan-results.md What KQL constructs actually get used
docs/licensing.md Third-party licensing review
demo/ Notebook tour of all three layers, with outputs
CONTRIBUTING.md How to add a mapping, and when not to
SECURITY.md Reporting vulnerabilities; what is in scope
Releases What changed, and when

Design

The KQL parser is generated by ANTLR from Microsoft's KQL grammar. Translation targets DuckDB SQL as a chain of Common Table Expressions (CTEs), one per KQL operator. DuckDB handles query optimization and execution.

Development

pip install -e ".[dev]"
pytest

tools/regen_parser.sh        # regenerate the parser (maintainers; needs Java)

The acceptance suite compares against the Kusto Emulator, which runs in Docker; see docs/oracle-harness.md.

License

MIT. See LICENSE, THIRD-PARTY-NOTICES.md, and licenses/.

Trademarks

"DuckDB" is a trademark of the DuckDB Foundation. "Kusto", "Azure", and "Azure Data Explorer" are trademarks of Microsoft Corporation. This project is independent and is not affiliated with, endorsed by, or sponsored by either the DuckDB Foundation or Microsoft. Product names are used descriptively, to indicate compatibility.

Download files

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

Source Distribution

duckdb_kql-0.0.15.tar.gz (903.6 kB view details)

Uploaded Source

Built Distribution

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

duckdb_kql-0.0.15-py3-none-any.whl (449.5 kB view details)

Uploaded Python 3

File details

Details for the file duckdb_kql-0.0.15.tar.gz.

File metadata

  • Download URL: duckdb_kql-0.0.15.tar.gz
  • Upload date:
  • Size: 903.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for duckdb_kql-0.0.15.tar.gz
Algorithm Hash digest
SHA256 de10cb651d47ffa68b23db76a30fb3cff0dc06842b2fce96e501f51c2f7c9c13
MD5 ef4f9a0e0480417bbaf7d9774ae0b2f6
BLAKE2b-256 0dab597ee1c8c4d0a439a36b177178a267578d67a48e09c9a36307ae0ad98ade

See more details on using hashes here.

Provenance

The following attestation bundles were made for duckdb_kql-0.0.15.tar.gz:

Publisher: release.yml on mmaitre314/duckdb-kql

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

File details

Details for the file duckdb_kql-0.0.15-py3-none-any.whl.

File metadata

  • Download URL: duckdb_kql-0.0.15-py3-none-any.whl
  • Upload date:
  • Size: 449.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for duckdb_kql-0.0.15-py3-none-any.whl
Algorithm Hash digest
SHA256 524cf4c3dba1a66692965901f8c4594338cc7652e58021e57f7314060859e106
MD5 0589ad8f3c0a96004bc206776b848c76
BLAKE2b-256 7dc61d6bfacb2f0009b5ee1c361a9ead22fa05ce5b2c40411530a12b9ebe4968

See more details on using hashes here.

Provenance

The following attestation bundles were made for duckdb_kql-0.0.15-py3-none-any.whl:

Publisher: release.yml on mmaitre314/duckdb-kql

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

Release history Release notifications | RSS feed

This release

0.0.15 This release

2 files

0.0.14

2 files

0.0.13

2 files

0.0.12

2 files

0.0.11

2 files

0.0.10

2 files

0.0.9

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

Supported by

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