Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Qenlo Python SDK

Type-safe Python bindings for Qenlo — the embedded, durable vector database written in Rust.

Qenlo provides exact filtered cosine vector search with atomic commits, write-ahead logging (WAL), portable .qn snapshot files, and zero external database services. Every search returns an execution report containing routing decisions, memory allocations, and hardware execution telemetry.

Installation

pip install qenlo

Pre-built binary wheels bundle the native Rust engine for:

  • Linux (x86_64, aarch64)
  • macOS (Apple Silicon arm64, Intel x86_64)
  • Windows (x86_64)

For source checkouts or development builds, set QENLO_LIBRARY_PATH to point to your compiled qenlo_ffi.dll, libqenlo_ffi.so, or libqenlo_ffi.dylib.


Quickstart

In-Memory Collection

from qenlo import Collection, Filter, Record

# Create an in-memory collection with 3-dimensional vectors
with Collection.memory(dimension=3) as db:
    # Insert records
    db.add(Record(id=1, user_id=42, timestamp=100, vector=(1.0, 0.0, 0.0)))
    db.add(Record(id=2, user_id=42, timestamp=200, vector=(0.0, 1.0, 0.0)))
    db.add(Record(id=3, user_id=99, timestamp=150, vector=(0.7, 0.7, 0.0)))

    # Search with combined user and timestamp filters
    response = db.search(
        query=(1.0, 0.0, 0.0),
        filter=Filter(user_id=42, timestamp_lower=50, timestamp_upper=150),
        k=5,
    )

    for hit in response.results:
        print(f"ID: {hit.id}, Cosine Distance: {hit.distance:.4f}")

    # Inspect hardware and routing telemetry
    report = response.report
    print(f"Backend: {report.actual_backend}, Algorithm: {report.algorithm}")
    print(f"Total Duration: {report.total_duration_ns} ns")

Durable Storage & Restarts

Qenlo collections can be persisted to disk with crash-safe write-ahead logging (WAL) and atomic compaction:

from qenlo import Collection, Record, Filter

path = "./my_collection.qenlo"

# 1. Create a new durable collection directory
with Collection.create(path, dimension=128) as db:
    db.add(Record(id=1, user_id=7, timestamp=10, vector=my_vector))
    db.flush()  # Compact and ensure full disk sync

# 2. Reopen across application restarts
with Collection.open(path, dimension=128) as db:
    response = db.search(query=my_query, filter=Filter(user_id=7), k=10)
    print(f"Found {len(response.results)} matches")

Portable .qn Interchange Files

Export and import standalone, checksummed, immutable .qn snapshots:

# Export an existing collection to a .qn file
db.export_qn("snapshots/v1.qn")

# Import from a .qn file into a fast in-memory collection
with Collection.import_qn("snapshots/v1.qn", dimension=128) as snapshot_db:
    stats = snapshot_db.stats()
    print(f"Loaded {stats.live_rows} rows from generation {stats.generation}")

Batch Operations

Qenlo supports high-throughput atomic batch mutations:

records = [
    Record(id=10, user_id=1, timestamp=1000, vector=(0.1, 0.2, 0.3)),
    Record(id=11, user_id=1, timestamp=1001, vector=(0.4, 0.5, 0.6)),
    Record(id=12, user_id=2, timestamp=1002, vector=(0.7, 0.8, 0.9)),
]

# Insert all atomically (all-or-nothing validation)
db.add_batch(records)

# Delete multiple records by ID
db.delete_batch([10, 11])

Data Model & Types

Record

  • id: int (unsigned 64-bit integer, unique and non-reusable)
  • user_id: int (unsigned 64-bit integer)
  • timestamp: int (signed 64-bit integer)
  • vector: Sequence[float] (normalized FP32 components)

Filter

  • user_id: Optional[int] (exact equality match)
  • timestamp_lower: Optional[int] (inclusive lower bound)
  • timestamp_upper: Optional[int] (exclusive upper bound)

ExecutionReport

  • operation_id: int — Unique monotonically increasing query ID
  • requested_backend: strCpu, GpuPredicate, or Automatic
  • actual_backend: str — Hardware engine that executed the search
  • algorithm: str — Search algorithm (Exact, IvfFlat, etc.)
  • filter_execution: str — Filter strategy evaluated
  • index_generation: int — Generation watermark observed
  • total_duration_ns: int — Total wall-clock time in nanoseconds
  • lock_wait_ns: int — Time spent acquiring read locks
  • eligible_rows: Optional[int] — Number of live rows passing metadata filters
  • upload_bytes: Optional[int] — Host-to-device bytes transferred
  • readback_bytes: Optional[int] — Device-to-host bytes read back

Error Handling

All native and validation failures raise QenloError or standard Python exceptions (ValueError):

from qenlo import Collection, QenloError, Record

try:
    with Collection.memory(3) as db:
        db.add(Record(1, 1, 0, (1.0, 0.0, 0.0)))
        # Duplicate IDs are strictly rejected
        db.add(Record(1, 1, 0, (0.0, 1.0, 0.0)))
except QenloError as e:
    print(f"Operation rejected: {e}")

Anonymous Telemetry Notice

Qenlo collects anonymous installation, execution, and hardware environment telemetry (OS platform, CPU architecture, SDK version, and search duration metrics) transmitted securely to https://api.gobitsnbytes.org/qenlo/telemetry. This telemetry is strictly anonymous, privacy-preserving, and mandatory across all SDK installations (there is no opt-out) in order to monitor stability, diagnose GPU driver regressions, and optimize embedded vector routing algorithms.


License

Dual-licensed under MIT or Apache-2.0 at your option.

Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

qenlo-0.1.0a1-py3-none-win_amd64.whl (267.4 kB view details)

Uploaded Python 3Windows x86-64

qenlo-0.1.0a1-py3-none-manylinux_2_28_x86_64.whl (396.8 kB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

qenlo-0.1.0a1-py3-none-macosx_14_0_arm64.whl (350.3 kB view details)

Uploaded Python 3macOS 14.0+ ARM64

File details

Details for the file qenlo-0.1.0a1-py3-none-win_amd64.whl.

File metadata

  • Download URL: qenlo-0.1.0a1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 267.4 kB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for qenlo-0.1.0a1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 f5fc8e899abfa93243244b48ae93ee69286cef4c6d9d3b16d55fe0d6ff84d64f
MD5 5e66fa302550c3f751ae4b41f4b2bcfc
BLAKE2b-256 d6c5b74495d2af5e1824b4abe0d704e87a3948517a259f1760df8b88303831c9

See more details on using hashes here.

File details

Details for the file qenlo-0.1.0a1-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for qenlo-0.1.0a1-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 37d736cab1a618448a4f0e5f8cb64629d4273581dc5602f66fa7c21f62949203
MD5 ba80f908d76f6e59d08aa37b606608ed
BLAKE2b-256 eae5620bd243f2da784d1178243fc1ec631221bcf51b5550c9681ef98fa95317

See more details on using hashes here.

File details

Details for the file qenlo-0.1.0a1-py3-none-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for qenlo-0.1.0a1-py3-none-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 478d04d158335e1a74998115acf4936db0cd5488a7f9abb2e0eaec4c817f7da1
MD5 83c7fae8ed324ee59cf7805bd2b6a3fa
BLAKE2b-256 87a1d781fad54e050162b584f7c8e05b86a2af8ddbdc37d8775aa50017c2075f

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0a1 This release

3 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