pyqql
Native Python bindings for QQL (parser, plan, execute) via PyO3.
Proposition
Write Qdrant operations as QQL instead of hand-built JSON. Same language as the
CLI and other SDKs: hybrid search, multitenancy (inject_filter + SHARD),
schema-as-code, REST or gRPC. Language surface tracks Qdrant ≥ 1.19
(quotas, memory placement, MATCH PREFIX / SLICE, sparse idf, turbo4).
Install
pip install pyqql
Python 3.10+ (stable ABI wheels). REST + gRPC included.
Quick start
import pyqql
embedder = pyqql.HttpEmbedder(
endpoint="http://localhost:11434/v1/embeddings",
model="all-minilm:l6-v2",
dimension=384,
)
client = pyqql.Client("http://localhost:6333", embedder=embedder)
report = client.execute(
"QUERY TEXT 'cardiology' FROM medical_records USING dense LIMIT 5"
)
print(report) # ExecutionReport: ok, results[], succeeded, failed
# Isolation (always on untrusted QQL)
stmt = pyqql.parse("QUERY TEXT 'risks' FROM sec10k USING dense LIMIT 10")[0]
pyqql.inject_filter(stmt, "tenant_id", "=", "honeywell")
# Routing (custom sharding): prefer SHARD in QQL, or set after parse
# QUERY ... SHARD 'honeywell' LIMIT 10
stmt.shard_key = "honeywell"
client.execute(stmt)
API summary
| Export | Role |
|---|---|
Client(url, api_key=None, use_grpc=False, embedder=None, route_affinity=None) |
Execute against Qdrant |
HttpEmbedder(endpoint, model, dimension, api_key="") |
OpenAI-compatible embeddings |
parse / parse_json / is_valid / tokenize |
Frontend — is_valid is the full gate (parse + plan), matching execution and the language conformance suite |
inject_filter(query|Stmt, field, op, value) |
Host isolation (AST) |
Stmt.shard_key |
Same field as QQL SHARD '…' (get/set; no inject_shard_key) |
compile / explain |
Offline plan / REST projection |
bind(query, params) |
Substitute :name (dict) or ? (list) |
execute / execute_async |
One-shot free functions (params= same as bind) |
execute_hits / execute_async_hits |
One-shot free functions returning List[ScoredPoint] |
ExecutionReport.hits/points/facet/count/groups |
Typed result accessors on every report |
connect(url, ...) + cursor |
PEP 249 driver: execute/executemany/fetchone/fetchmany/fetchall/nextset/iteration, description, rowcount; commit() no-op, rollback() raises |
Client.explain_analyze |
Static plan + measured client/server timings for one statement |
report.telemetry |
Per-result server telemetry (time_s, hardware/inference usage) when reported |
inject_filter operators
Accepted: =, >, >=, <, <= (and aliases).
Rejected: !=, IN, … — write those in QQL or inject equality only.
Isolation vs routing
| Concern | API | Wire |
|---|---|---|
| Isolation | inject_filter / WHERE |
REST/gRPC Filter |
| Routing | SHARD '…' or stmt.shard_key |
REST shard_key / gRPC ShardKeySelector |
| Partition DDL | CREATE SHARD KEY '…' |
Admin shard-key API |
Qdrant 1.19 notes
# Quotas: REST only (default Client URL :6333). use_grpc=True → QQL-GRPC-QUOTA
client.execute("SHOW QUOTAS")
client.execute(
"SET QUOTA (enabled = true, max_resident_memory_percent = 80, "
"max_disk_usage_percent = 90, release_margin_percent = 5) WAIT true"
)
# Filters / DDL that require Qdrant ≥ 1.19
client.execute(
"CREATE INDEX ON COLLECTION docs FOR title TYPE keyword "
"WITH (prefix = true, memory = 'cached')"
)
client.execute(
"QUERY TEXT 'q' FROM docs USING dense WHERE title MATCH PREFIX 'Comp' LIMIT 5"
)
client.execute(
"QUERY TEXT 'q' FROM docs USING sparse PARAMS (idf = 'global') LIMIT 5"
)
client.execute(
"QUERY TEXT 'q' FROM docs USING sparse "
"WHERE tenant_id = 'acme' SHARD 'acme' "
"PARAMS (idf = WHERE tenant_id = 'acme') LIMIT 5"
)
SET QUOTA is a full replace of the cluster config.
Route affinity (Qdrant 1.19+)
Pin reads to a stable replica with route_affinity at construction — sent as
the X-Qdrant-Route-Affinity header (REST) / x-qdrant-route-affinity metadata
(gRPC). Empty string is treated as unset. Readable via client.route_affinity.
client = pyqql.Client("http://localhost:6333", route_affinity="session-acme-42")
print(client.route_affinity) # "session-acme-42"
# One-shot convenience:
pyqql.execute("SHOW COLLECTIONS", url="http://localhost:6333", route_affinity="session-acme-42")
Execution report
{
"ok": True,
"results": [{"ok": True, "operation": "QUERY", "message": "…", "data": …}],
"succeeded": 1,
"failed": 0,
}
on_error="stop" (default) or "continue".
Formula queries vs Qdrant SDK FormulaQuery
In QQL, custom formula scoring is declarative SQL-like syntax executed directly:
report = client.execute("""
QUERY FORMULA score * 0.8 + LOG(views + 1.0) * 0.2
DEFAULTS (score = 0.0, views = 0)
FROM articles
LIMIT 10
""")
Important: Do not wrap QQL strings in
qdrant_client.models.FormulaQuery! In the official Qdrant Python SDK,FormulaQueryexpects an object tree ofExpressionclasses (e.g.models.SumExpression(...)), not query text. Pass formula queries directly toclient.execute().Shell quoting: Prefer bare
scoreinstead of$score. While$scoreworks inside Python strings, POSIX shells (bash, zsh) interpolate$scoreinto""when run via CLI or shell scripts. Barescoreis shell-safe across all environments.
Docs
Metadata
Release files for pyqql 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| pyqql-0.5.0-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| pyqql-0.5.0-cp310-abi3-manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ x86-64 | Details |
| pyqql-0.5.0-cp310-abi3-manylinux_2_28_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ ARM64 | Details |
| pyqql-0.5.0-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 17.1 MB
Release files / pyqql-0.5.0-cp310-abi3-win_amd64.whl
| Download URL | pyqql-0.5.0-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 4.6 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
54c5be1f98004ed35a8d74986241937dbf7a7c636244f83f09e32d56337b926e
|
|
BLAKE2b-256 checksum How to use checksums |
be7cb6a65bc3bdc6792255db7c819507aac934f9592567d005c16dd6f3636b5d
|
| 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 1, 2026.
Transparency logRelease files / pyqql-0.5.0-cp310-abi3-manylinux_2_28_x86_64.whl
| Download URL | pyqql-0.5.0-cp310-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 4.4 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
500134e168a0675a4825616612967f4e5b98df2c65dfac3878e94fdfca2c5cfe
|
|
BLAKE2b-256 checksum How to use checksums |
b12074d5a8362a03297f69cfc56c0ffcb96a85d07bd8ba6a72f17dc2379fceb3
|
| 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 1, 2026.
Transparency logRelease files / pyqql-0.5.0-cp310-abi3-manylinux_2_28_aarch64.whl
| Download URL | pyqql-0.5.0-cp310-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 4.2 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
a855186fa39904e9570d8577ce45448f1538af76473d5171885735799b36f677
|
|
BLAKE2b-256 checksum How to use checksums |
9e91771a7a667723b12a795cb10138f9539548b406ae8096a950057c816c9b0c
|
| 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 1, 2026.
Transparency logRelease files / pyqql-0.5.0-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | pyqql-0.5.0-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 4.0 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
3ab4c15255dc98825c00943bcd6cd158dae05c4f0e49e214c6789d7e6d88d54e
|
|
BLAKE2b-256 checksum How to use checksums |
a8d36143832a66113adbe287b9e5ced445396e2babdcb2e1b60c9b2d977c6618
|
| 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 1, 2026.
Transparency log