Skip to main content
Pre-release

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

pylibseekdb

Low-level Python bindings for the seekdb C client library.

🚀 What is OceanBase seekdb?

OceanBase seekdb is an AI-native search database that unifies relational, vector, full-text, JSON, and GIS in a single engine, enabling hybrid search and in-database AI workflows.

📖 Read the launch blog → · 📚 Docs →

✨ Why seekdb for Agents?

🔥 Streaming Write + Concurrent Search, Without the P99 Spike

Agent workloads are continuous write + millisecond-later read. seekdb's async index pipeline (Change Stream) decouples DML from index build, and its two-level HNSW (incremental + snapshot) makes newly-written vectors immediately searchable.

seekdb async index pipeline architecture

The write path commits and returns without waiting on index construction. The Change Stream pipeline consumes the redo log asynchronously and updates the delta HNSW. Queries hit both delta and snapshot indexes with fine-grained read locks — this is why P99 stays flat under concurrency.

🌿 Copy-on-Write Sandboxes for Agent Exploration

FORK DATABASE snapshots an entire database in seconds — no data copy. Agents experiment freely (write, query, even break tables); then MERGE TABLE commits the work back, or DROP DATABASE discards it.

🔍 Hybrid Search in a Single SQL

Vector + full-text + scalar filter pushed into one execution plan. No N+1 client-side merging, no glue code to combine results.

🐬 MySQL-Compatible, ACID, Embeddable

Built on the proven OceanBase SQL engine. Works as an embedded library, a single-node server, or in the OceanBase distributed cluster. Full ACID, real-time writes, and the entire MySQL ecosystem out of the box.

Installation

pip install pylibseekdb

Requirements

  • CPython >= 3.11
  • Linux x86_64 or aarch64 with glibc >= 2.28 (Alpine / musl not supported yet)
  • macOS arm64 >= 15.6

🎬 Quick Start

pylibseekdb exposes a lightweight DB-API 2-style interface directly over the seekdb C driver. It currently starts a local seekdb runtime via open(). Native embedded-mode support will be released soon.

import pylibseekdb as seekdb

# Start a local seekdb runtime (embedded-mode support will be released soon)
seekdb.open(db_dir="./seekdb.db")

# Get a connection and a cursor
conn   = seekdb.connect(database="test", autocommit=True)
cursor = conn.cursor()

# Create a table with a vector column and an HNSW index
cursor.execute("""
    CREATE TABLE IF NOT EXISTS articles (
        id        INT PRIMARY KEY,
        title     TEXT,
        embedding VECTOR(4),
        VECTOR INDEX idx_vec (embedding)
            WITH (DISTANCE=l2, TYPE=hnsw, LIB=vsag)
    ) ORGANIZATION = HEAP
""")

# Insert a row
cursor.execute(
    "INSERT INTO articles VALUES (1, 'Hello seekdb', '[0.1, 0.2, 0.3, 0.4]')"
)

# Hybrid / vector search
cursor.execute("""
    SELECT id, title,
           l2_distance(embedding, '[0.1, 0.2, 0.3, 0.4]') AS dist
    FROM articles
    ORDER BY dist APPROXIMATE
    LIMIT 5
""")
rows = cursor.fetchall()
for row in rows:
    print(row)

cursor.close()
conn.close()
seekdb.close()

Multiple instances

One process can manage multiple local seekdb runtimes through the SeekdbInstance objects returned by open():

import pylibseekdb as seekdb

first = seekdb.open("./first.db")
second = seekdb.open("./second.db")

first_connection = first.connect(database="test")
second_connection = second.connect(database="test")

first_connection.close()
second_connection.close()
first.close()
second.close()

Each instance uses the local socket inside its normalized database directory, so no additional port configuration is needed. The first successful open() also becomes the module's default instance, preserving the legacy seekdb.connect(), seekdb.connection_options(), and seekdb.close() API. Later calls return independent instance objects without changing that default. Use the object methods for additional instances.

Connect with PyMySQL

connection_options() returns endpoint and authentication arguments shared by Python MySQL-protocol drivers. Install the driver separately:

pip install PyMySQL
import pymysql
import pylibseekdb as seekdb

instance = seekdb.open(db_dir="./seekdb.db")
options = instance.connection_options()

connection = pymysql.connect(database="test", **options)
try:
    with connection.cursor() as cursor:
        cursor.execute("SELECT 1")
        print(cursor.fetchone())
finally:
    # External connections must release the server before its lifecycle handle.
    connection.close()
    instance.close()

On Unix, options contains only user="root" and unix_socket. For TCP it contains only user="root" and port; the driver supplies its default local host. The database name remains caller-owned because PyMySQL uses database while aiomysql uses db. Treat the returned dictionary as lifecycle-scoped: do not use it after closing its SeekdbInstance.

Async initialization and aiomysql

Install aiomysql separately:

pip install aiomysql
import asyncio

import aiomysql
import pylibseekdb as seekdb


async def main():
    instance = await seekdb.aopen(db_dir="./seekdb.db")
    options = instance.connection_options()
    pool = await aiomysql.create_pool(
        db="test",
        minsize=1,
        maxsize=5,
        **options,
    )
    try:
        async with pool.acquire() as connection:
            async with connection.cursor() as cursor:
                await cursor.execute("SELECT 1")
                print(await cursor.fetchone())
    finally:
        pool.close()
        await pool.wait_closed()
        instance.close()


asyncio.run(main())

aopen() runs the synchronous C startup operation in a worker thread and returns a SeekdbInstance, so it does not block the asyncio event loop. Cancelling the coroutine cannot stop seekdb_open() after that worker starts.

Transaction support

conn = seekdb.connect(database="test", autocommit=False)
cursor = conn.cursor()
try:
    conn.begin()
    cursor.execute("INSERT INTO articles VALUES (2, 'Second', '[0.5,0.6,0.7,0.8]')")
    conn.commit()
except seekdb.SeekdbError:
    conn.rollback()
    raise
finally:
    cursor.close()
    conn.close()

SQL — Hybrid Search

-- Create table with vector column, full-text index, and HNSW vector index
CREATE TABLE docs (
    id        INT PRIMARY KEY,
    title     TEXT,
    content   TEXT,
    embedding VECTOR(384),
    FULLTEXT INDEX idx_fts (content) WITH PARSER ik,
    VECTOR   INDEX idx_vec (embedding)
        WITH (DISTANCE=l2, TYPE=hnsw, LIB=vsag)
) ORGANIZATION = HEAP;

-- Hybrid search: vector similarity + full-text match in one query
SELECT id, title,
       l2_distance(embedding, '[0.12, 0.34, ...]') AS dist
FROM docs
WHERE MATCH(content) AGAINST('quarterly report')
ORDER BY dist APPROXIMATE
LIMIT 10;

API Reference

Module-level functions

Function Description
open(db_dir="./seekdb.db") Start a local runtime and return its SeekdbInstance. The first open instance becomes the module default.
await aopen(db_dir="./seekdb.db") Run open() in a worker thread and return its SeekdbInstance.
connection_options() Return connection arguments for the default instance. The database name is not included.
connect(database="test", autocommit=False) Return a Connection to the default instance.
close() Close and clear the default instance. Idempotent.

SeekdbInstance

Attribute or method Description
db_dir Normalized absolute database directory used by this instance.
closed Whether this instance has been closed.
connect(database="test", autocommit=False) Return a Connection to this instance.
connection_options() Return connection arguments for PyMySQL or aiomysql.
close() Release this instance. Existing native Connection objects keep the underlying lifecycle handle alive until they close.

Connection

Method Description
cursor() Return a new Cursor.
begin() Begin a transaction.
commit() Commit the current transaction.
rollback() Roll back the current transaction.
close() Disconnect and release resources.

Cursor

Method Description
execute(sql) Execute sql; returns the number of rows in the result set (0 for statements without a result set).
fetchone() Return the next row as a tuple, or None.
fetchall() Return all remaining rows as a list of tuple.
close() Free the result set.

SeekdbError

Exception raised on driver errors. Subclass of RuntimeError.

📚 Use Cases

  • 🤖 Agentic AI — streaming memory writes, millisecond-later vector retrieval, FORK DATABASE for safe exploration
  • 📖 RAG & Knowledge Retrieval — hybrid search across enterprise knowledge bases
  • 🔍 Semantic Search — embedding-based search for text, images, and other modalities
  • 💻 AI-Assisted Coding — semantic code search with multi-project isolation
  • 📱 On-Device & Edge AI — lightweight local deployments today, with embedded-mode support coming soon

🌐 Resources

License

Apache-2.0 — see LICENSE.

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.

pylibseekdb-1.3.0.dev5-cp312-abi3-manylinux_2_28_x86_64.whl (126.1 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.28+ x86-64

pylibseekdb-1.3.0.dev5-cp312-abi3-manylinux_2_28_aarch64.whl (111.2 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.28+ ARM64

pylibseekdb-1.3.0.dev5-cp312-abi3-macosx_15_0_arm64.whl (110.7 MB view details)

Uploaded CPython 3.12+macOS 15.0+ ARM64

pylibseekdb-1.3.0.dev5-cp311-cp311-manylinux_2_28_x86_64.whl (126.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

pylibseekdb-1.3.0.dev5-cp311-cp311-manylinux_2_28_aarch64.whl (111.3 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

pylibseekdb-1.3.0.dev5-cp311-cp311-macosx_15_0_arm64.whl (110.7 MB view details)

Uploaded CPython 3.11macOS 15.0+ ARM64

File details

Details for the file pylibseekdb-1.3.0.dev5-cp312-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.3.0.dev5-cp312-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0dd52397c45e4194b75c4ceb1dce3e363a42184c7db0a6ab43db4c1b1d86ce4c
MD5 c3a2b89c4581c6cfcd815a03ea549713
BLAKE2b-256 c8b3d1e9d6c73b9e3b2c5a3f00a8403c4cb518c048a07a43a5c6685f23c20b5e

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.3.0.dev5-cp312-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.3.0.dev5-cp312-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e82c8b53415f117071bef0059ec072ba35a6db0d7ff57af0fee596fef96520a1
MD5 439acfbe70ce04e3850b6eb277763cb4
BLAKE2b-256 8c77fa99c4bba48e6611b59a70ceef362b8d0ddcbb89c8ccb80463d84f7780de

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.3.0.dev5-cp312-abi3-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.3.0.dev5-cp312-abi3-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 d09e9cf2e56fdc00690b5327610479f4a3612898d11831aa5a77224fdaa69a79
MD5 499d67da0eb94c7c8ea5b7ce59923d59
BLAKE2b-256 d3fe84595a7cbb26cf880164baa20d5bbe1629f4d0a16e3c0a5d6e40fa2488f6

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.3.0.dev5-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.3.0.dev5-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e9019b957b0b91913d7d64bd48e1331b1839598d0c9cab221189a317d98a2fb4
MD5 b16842ba91a321cefa499fb1e7cdd805
BLAKE2b-256 f5fab6620cc5d82c70ab6d2e8913a07c92143f7b928024c075ecf203d2cfce6c

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.3.0.dev5-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.3.0.dev5-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 cb160499365cb3a986964cae67189e99601d45204a066388d8fa8ccbcf06009c
MD5 d124564188fad97bef192c94681f3189
BLAKE2b-256 678487216b3d63c6a9de4b11439437304dca4335401587be5add5439c59a7d40

See more details on using hashes here.

File details

Details for the file pylibseekdb-1.3.0.dev5-cp311-cp311-macosx_15_0_arm64.whl.

File metadata

File hashes

Hashes for pylibseekdb-1.3.0.dev5-cp311-cp311-macosx_15_0_arm64.whl
Algorithm Hash digest
SHA256 13f2ed398673cbdb7c740a301073407d6c8ab96c1407f065047c3e37cd80ba1b
MD5 73d0cf9879501caee52ce25a19c442fe
BLAKE2b-256 09081093b2d633423cd4a9b3ecf24bd8b6881d197d5dca645a895709955991a7

See more details on using hashes here.

Release history Release notifications | RSS feed

1.4.0.post1

8 files

1.4.0

8 files

1.4.0.dev2

1.3.0.post5

8 files

1.3.0.post4

8 files

1.3.0.post3

12 files

1.3.0

18 files

This release

1.3.0.dev5 This release

6 files

1.2.0

18 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