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
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
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 duckdb_kql-0.0.14.tar.gz.
File metadata
- Download URL: duckdb_kql-0.0.14.tar.gz
- Upload date:
- Size: 897.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1dc0efbc01532dcef994ee92199b3fdb611cc1704ad91d19f74cca7eb59de30
|
|
| MD5 |
fb6c3dea5a3f1ef3393a5f355e6d783b
|
|
| BLAKE2b-256 |
156a913a14af47d78f7d24e97d7b81e24685b80ce55dc9978c6d59573b270526
|
Provenance
The following attestation bundles were made for duckdb_kql-0.0.14.tar.gz:
Publisher:
release.yml on mmaitre314/duckdb-kql
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
duckdb_kql-0.0.14.tar.gz -
Subject digest:
e1dc0efbc01532dcef994ee92199b3fdb611cc1704ad91d19f74cca7eb59de30 - Sigstore transparency entry: 2581958660
- Sigstore integration time:
-
Permalink:
mmaitre314/duckdb-kql@57a32e7a8cffc8a20a76a6d3bbae44a1e3db2fa1 -
Branch / Tag:
refs/tags/v0.0.14 - Owner: https://github.com/mmaitre314
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@57a32e7a8cffc8a20a76a6d3bbae44a1e3db2fa1 -
Trigger Event:
release
-
Statement type:
File details
Details for the file duckdb_kql-0.0.14-py3-none-any.whl.
File metadata
- Download URL: duckdb_kql-0.0.14-py3-none-any.whl
- Upload date:
- Size: 447.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7737297941aeb1c81712bb6ee6bdc47cd12c35bf7843a5cc5f339adb27afb784
|
|
| MD5 |
49b387a66b74cd9541afcc609e1b692f
|
|
| BLAKE2b-256 |
ebb5c708aa00e9f67313c603cf109b5ed917430b339ddf345cbc67e0eeb8137e
|
Provenance
The following attestation bundles were made for duckdb_kql-0.0.14-py3-none-any.whl:
Publisher:
release.yml on mmaitre314/duckdb-kql
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
duckdb_kql-0.0.14-py3-none-any.whl -
Subject digest:
7737297941aeb1c81712bb6ee6bdc47cd12c35bf7843a5cc5f339adb27afb784 - Sigstore transparency entry: 2581958667
- Sigstore integration time:
-
Permalink:
mmaitre314/duckdb-kql@57a32e7a8cffc8a20a76a6d3bbae44a1e3db2fa1 -
Branch / Tag:
refs/tags/v0.0.14 - Owner: https://github.com/mmaitre314
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@57a32e7a8cffc8a20a76a6d3bbae44a1e3db2fa1 -
Trigger Event:
release
-
Statement type: