Skip to main content

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, FormulaQuery expects an object tree of Expression classes (e.g. models.SumExpression(...)), not query text. Pass formula queries directly to client.execute().

Shell quoting: Prefer bare score instead of $score. While $score works inside Python strings, POSIX shells (bash, zsh) interpolate $score into "" when run via CLI or shell scripts. Bare score is 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)

Table of built distributions (wheels) for pyqql 0.5.0
File
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 log

Release 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 log

Release 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 log

Release 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

Release history Release notifications | RSS feed

This release

0.5.0 This release

4 release files

0.4.2

4 release files

0.4.1

4 release files

0.4.0

5 release files

0.3.1

4 release files

0.3.0

4 release files

0.2.1

4 release files

0.2.0

4 release files

0.1.5

4 release files

0.1.4

4 release files

0.1.3

4 release files

0.1.2

4 release files

0.1.1

4 release files

0.1.0

4 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