Skip to main content

skeg-py

Python client for skeg, an SSD-primary KV+vector store designed for Personal AI Inference machines.

pip install skeg              # pure-Python
pip install 'skeg[fast]'      # PyO3-backed (binary wheels for macOS arm64, Linux x86_64, Linux aarch64)

RESP3 is the supported protocol. It carries the whole command surface, and it is the one to reach for unless you have a specific reason not to. The native binary client covers a smaller set of operations and is kept for existing callers.

import skeg

with skeg.connect() as c:  # RESP3 on 6379, HELLO already negotiated
    c.set(b"hello", b"world")

Two entry points, and they are not interchangeable:

Call Wire Port Surface
skeg.connect() RESP3 6379 Everything
skeg.client() native binary 7379 KV + basic vectors

What's in the package

Two synchronous clients sharing one error hierarchy:

Module Wire Server binary Default port Use case
skeg.RespClient RESP2/3 (Redis) skeg-resp3 6379 Recommended. Full surface: KV, vectors, tenancy, quotas. Also a drop-in for redis-cli / redis-py
skeg.BinaryClient skeg-proto (native) skeg 7379 Lower framing overhead, smaller surface. No payloads, filters or tenancy

What only RESP3 can do: vector payloads (WITHPAYLOAD), search filters, VMSET bulk insert, index consolidation, and every tenancy, quota and QoS command. The native protocol has no equivalent for any of them.

Three backends behind one selector (skeg.client(...)):

  • Pure-Python (default, zero deps) - just pip install skeg
  • PyO3 / Rust (optional, faster framing) - pip install skeg[fast] (requires Rust toolchain at install time, or a pre-built wheel)

The PyO3 path mirrors BinaryClient's public API, so you can swap with no code changes:

import skeg

c = skeg.client(prefer_native=True)  # uses PyO3 if available
c = skeg.client(prefer_native=False)  # forces pure-Python

Both backends speak native protocol v1 and v2, including native_hello(), supports_kind() and the TurboQuant kinds:

import skeg
from skeg import _wire as wire

c = skeg.client(prefer_native=True, version=wire.VERSION_V2)
if c.supports_kind("tq2"):
    c.vindex_create("notes", dim=1024, kind="tq2", backend="disk")

tests/test_backend_parity.py compares the two surfaces and fails both ways: when the compiled backend loses a method, and when a method listed as missing comes back. So the two cannot drift apart quietly.

Install

pip install skeg              # pure-Python, zero dependencies
pip install 'skeg[fast]'      # PyO3-backed; binary wheels for macOS arm64, Linux x86_64, Linux aarch64

To build from source (e.g. on Windows or another arch), pip install will compile the PyO3 backend; set SKEG_PY_PURE=1 to skip it.

Quick start

KV

import skeg

with skeg.connect("127.0.0.1", 6379) as c:
    c.set(b"hello", b"world")
    print(c.get(b"hello"))  # b"world"
    print(c.mget([b"hello", b"nope"]))  # [b"world", None]
    print(c.append(b"hello", b"!"))  # 6 - the new length
    print(c.incr(b"counter"))  # 1
    c.delete(b"hello")

Vectors

import skeg

with skeg.connect() as c:
    # kind: f32 | int8 | binary | tq1 | tq2 | tq4. Omit it for the
    # server default, tq2 - near-f32 recall at a fraction of the RAM.
    c.vindex_create("notes", dim=1024, backend="flat")
    c.vset("notes", 1, my_embedding_1024d)
    c.vset("notes", 2, another_embedding, payload=b"chapter-3")

    for hit in c.vsearch("notes", query_embedding, k=10):
        print(hit.id, hit.score)

    # Payloads come back only when asked for, and can be filtered on.
    for hit in c.vsearch(
        "notes", query_embedding, k=10, with_payload=True, filter="tenant=alice"
    ):
        print(hit.id, hit.score, hit.payload)

Bulk insert in one round trip:

c.vmset("notes", [(1, vec_a, b"payload-a"), (2, vec_b, None)])
c.vindex_consolidate("notes")  # fold the disk delta into the graph

Vectors (on-disk Vamana)

Build the index offline (one-shot), then point the client at the served copy:

skeg-cli build --input embeddings.npy --output ./data --name notes
skeg --mode serve --data-dir ./data --tier pq:128:256
# Same client code as above; the server handles the disk-backed index.
hits = c.vsearch("notes", query, k=10)

Multi-tenant

c.hello(3, auth=("alice", "hunter2"))
print(c.skeg_whoami())  # "tenant=<hex> mode=tenant-aware"
# All subsequent GET/SET are auto-scoped to alice's namespace.

c.subject_erase(b"user:42:")  # erase one data subject, returns a count
c.quota_set("alice", max_vectors=1_000_000, max_disk_bytes=None)  # None = unlimited
c.qos_set("alice", rate=500, burst=1000, max_concurrent=8)
c.reclaim()  # admin: physically free erased bytes

Erasure is logical: the bytes leave the disk on a later reclaim().

Native binary protocol

Smaller surface, less framing overhead. Two wire versions:

from skeg import BinaryClient, VectorKindV2
from skeg import _wire as wire

# v1 (default): f32, int8 and binary kinds only.
with BinaryClient.connect("127.0.0.1", 7379) as c:
    c.vindex_create("notes", dim=1024, kind="int8")

# v2: adds the TurboQuant kinds and capability negotiation.
with BinaryClient.connect("127.0.0.1", 7379, version=wire.VERSION_V2) as c:
    protocol_version, kind_mask = c.native_hello()
    if c.supports_kind("tq2"):
        c.vindex_create("notes", dim=1024, kind="tq2")

Kind byte 3 means different things in the two versions: PQ in v1, TQ1 in v2. That collision is why v2 exists, and why VectorKindV2 is a separate enum from VectorKind rather than extra variants on it. A v1 connection asking for byte 3 is refused by the server rather than silently given the wrong index.

Testing

brew tap skegdb/tap
brew install skeg
git clone https://github.com/skegdb/skeg-py
cd skeg-py
pip install -e '.[test]'
SKEG_BIN=$(which skeg) SKEG_RESP3_BIN=$(which skeg-resp3) pytest

The fixture spawns one server per session and tears it down at the end. Both env vars are required: skeg-py used to live inside the skeg repo, where the binaries could be found by relative path, and no longer does. Tests that need a server skip without them.

Conformance suite

Command coverage is not asserted by hand here. tests/test_conformance_resp3.py and tests/test_conformance_native.py run the shared case files that every skeg client is checked against, driving this SDK's public methods:

SKEG_CONFORMANCE_DIR=<skeg-internal>/conformance \
SKEG_BIN=$(which skeg) SKEG_RESP3_BIN=$(which skeg-resp3) pytest

Without SKEG_CONFORMANCE_DIR those tests skip. Cases marked wire_only are skipped by design: they are things a typed SDK cannot express - a GET with no key, an unknown command - and the case files ship standalone validators that cover them against the raw wire.

Test-suite safety vs your data

The pytest suite is designed for a server it owns. It writes keys under names like doc:N, counter:N, sk-N, and creates/drops VINDEX entries prefixed with pytst-. If you ever override the default fixture to point the suite at a server that already holds real data:

  • KV: keys with the names above will be overwritten or deleted.
  • VINDEX: only entries that match the pytst- prefix are touched by the cleanup loop. Unrelated VINDEX are left alone.

In short: never point pytest at a server you can't afford to lose KV state on. The pytest-spawned fixture is the safe default.

Compatibility

  • Python 3.10+ (one abi3 wheel covers 3.10, 3.11, 3.12, 3.13).
  • macOS arm64, Linux x86_64, Linux aarch64 (wheels). Other targets build from sdist; set SKEG_PY_PURE=1 to skip the PyO3 backend.
  • RESP2 and RESP3, and native protocol versions 1 and 2. All stable.

License

Apache-2.0. See LICENSE.

Release files for skeg 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for skeg 0.2.0
File Size Uploaded
skeg-0.2.0.tar.gz 33.6 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for skeg 0.2.0
File Interpreter ABI Platform
skeg-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.10 abi3 Linux glibc 2.17+ x86-64 Details
skeg-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.10 abi3 Linux glibc 2.17+ ARM64 Details
skeg-0.2.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details

Total release size: 1.4 MB

Release files / skeg-0.2.0.tar.gz

Download URL skeg-0.2.0.tar.gz
Size 33.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9e3795bf8c1628e85459f6dbaf02aa29d86bd29d167ae50115aba97b8c6c1c49
BLAKE2b-256 checksum
How to use checksums
66d36bb6db052e3803def98b216ba93226618562a47a97892ad5638b1f4bfd8a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / skeg-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL skeg-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 495.3 kB
Tags CPython 3.10 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
f2bbdf3c0854eee958df7bf83ec6530a55102fb956e6cc69bbea5f0f34d81dd9
BLAKE2b-256 checksum
How to use checksums
bc26f3cc70a59c416fe969e3d4ac47b87c888841f161c0e758503d22d404967c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / skeg-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL skeg-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 489.4 kB
Tags CPython 3.10 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
2d800fd7a2622980e644d999d9d807d79d612b0a77d9089ad1e0bc50418d76ad
BLAKE2b-256 checksum
How to use checksums
1a38b9d631a2a9a9dd6d3fe29ddebea1093a797ddbc6d31a30271bca4b46cb50
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release files / skeg-0.2.0-cp310-abi3-macosx_11_0_arm64.whl

Download URL skeg-0.2.0-cp310-abi3-macosx_11_0_arm64.whl
Size 424.8 kB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
a65a16e1a2dbeec065f71694191e6e7d9f161e5526e9ad3f4320631c14151e21
BLAKE2b-256 checksum
How to use checksums
ef95cb0667ad34935c10e367f6afc023048b635402158d82f857fe2959eb4906
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via maturin/1.14.1

Release history Release notifications | RSS feed

This release

0.2.0 This release

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