Skip to main content

murr-python

Async Python client for murr, a RocksDB-based NVMe/S3 cache for AI inference workloads.

The client is pure Python: it talks to a murr server over HTTP, with Arrow IPC for data and JSON for schemas. Version 0.3.x of the client needs a 0.3.x server.

Install

pip install murr

Quickstart

Start a server:

docker run -p 8080:8080 ghcr.io/murrdb/murr:0.3.0

and then:

import asyncio

import pyarrow as pa
from murr.client import Client, ColumnSchema, DType, TableSchema


async def main():
    async with Client("http://localhost:8080") as db:
        await db.create_table("docs", TableSchema(columns={
            "id":       ColumnSchema(dtype=DType.UTF8, nullable=False, key=True),
            "score":    ColumnSchema(dtype=DType.FLOAT32),
            "category": ColumnSchema(dtype=DType.UTF8),
        }))

        await db.write("docs", pa.table({
            "id":       ["doc_1", "doc_2", "doc_3"],
            "score":    pa.array([0.95, 0.72, 0.68], pa.float32()),
            "category": ["ml", "infra", "ops"],
        }))

        result = await db.read("docs", {"id": ["doc_3", "doc_1"]}, columns=["score", "category"])
        print(result.to_pandas())


asyncio.run(main())

read returns a pyarrow.Table with the requested columns. Row i answers key i, and a key which is not in the table gives a row of nulls.

API

Method What it does
create_table(name, schema) Create a table
drop_table(name) Drop a table
list_tables() All tables as {name: TableSchema}
get_schema(name) Schema of one table
write(table, data) Write a pa.Table or pa.RecordBatch
read(table, keys, columns) Read columns for a batch of keys
compact(table) Compact a table, returns when it is done

All methods are coroutines. There is no blocking client: wrap a call in asyncio.run if you need one.

Schemas

A column has a dtype, and optional nullable (default True), key (default False) and strict (default True) flags. Supported dtypes are utf8, bool, int8 to int64, uint8 to uint64, float32 and float64.

A table needs at least one key column. Key columns must be nullable=False and of a utf8 or integer dtype. Several key columns form a compound key:

schema = TableSchema(columns={
    "user":  ColumnSchema(dtype=DType.UTF8,  nullable=False, key=True),
    "item":  ColumnSchema(dtype=DType.INT64, nullable=False, key=True),
    "score": ColumnSchema(dtype=DType.FLOAT64),
})

await db.create_table("ratings", schema)
await db.read("ratings", {"user": ["u1", "u2"], "item": [1, 7]}, columns=["score"])

Keys

Keys go to the server as an Arrow table with one column per key column. Pass a pa.Table, a pa.RecordBatch, or a {name: values} mapping which is turned into a table with pa.table().

The server widens types (an int32 array is fine for an int64 key) but never narrows them. Python ints become int64, so a narrower key column needs a typed array:

await db.read("events", {"id": pa.array([1, 2], pa.int32())}, columns=["flag"])

The same holds for writes, with one addition: writing float64 values into a float32 column rounds them, and is only accepted for a column created with strict=False.

Errors

Server errors are raised as subclasses of MurrError, which carries the HTTP status_code and the server message:

Exception When
TableNotFoundError the table does not exist
TableAlreadyExistsError create_table for an existing name
InvalidRequestError bad schema, wrong key types, unknown column
ServerError the server failed to process the request

Development

uv sync --extra dev
uv run pytest tests/ -v

The tests start ghcr.io/murrdb/murr:0.3.0 in Docker through testcontainers. Set MURR_IMAGE to test against another image, or MURR_ENDPOINT to use a server which is already running.

Releases

Set version in pyproject.toml and push a matching v<version> tag, like v0.3.0. The release workflow runs the tests, checks that the tag matches the package version, publishes the sdist and wheel to PyPI, and then creates a GitHub release.

License

Apache-2.0.

Metadata

Release files for murr 0.3.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 murr 0.3.0
File Size Uploaded Provenance Actions
murr-0.3.0.tar.gz 53.8 kB Without provenance Details for murr-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for murr 0.3.0
File Interpreter ABI Platform Actions
murr-0.3.0-py3-none-any.whl Python 3 none any Details for murr-0.3.0-py3-none-any.whl

Total release size: 64.8 kB

Release files / murr-0.3.0.tar.gz

Download URL murr-0.3.0.tar.gz
Size 53.8 kB
Tags Source
SHA-256 checksum
How to use checksums
1119f3eeeb06fefafca45fd42429b1ced4921accbf9a81c0142b7d23a9f8f3bb
BLAKE2b-256 checksum
How to use checksums
f44a45530f102b6625de8b1d38fce8c9cab9243830a832e3678bdfaa5863f24e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / murr-0.3.0-py3-none-any.whl

Download URL murr-0.3.0-py3-none-any.whl
Size 11.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8809df7d74b73386911e10ea213ef7d0b39348d81b7ea843cca3a2ac8776d6b2
BLAKE2b-256 checksum
How to use checksums
5bb757d422fc533a1ead9fbc79dc55826fd3e5635993afe5807d0c31c9008d91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for murr 0.3.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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