Skip to main content

Python bindings for the Lora in-memory graph database

Project description

lora-python

Python bindings for the Lora graph engine. Ships both a synchronous PyO3 Database class and an asyncio-compatible AsyncDatabase wrapper that never blocks the event loop.

Package: lora-python.

Install (local dev)

cd crates/bindings/lora-python
python3 -m venv .venv && source .venv/bin/activate
pip install -U pip maturin pytest pytest-asyncio
maturin develop         # builds the Rust extension into the venv
pytest                  # runs the sync + async smoke tests

maturin develop produces a lora_python/_native.<platform>.so inside the package and makes import lora_python work immediately.

Sync usage

from lora_python import Database, is_node

db = Database.create()
db.execute("CREATE (:Person {name: $n, age: $a})", {"n": "Alice", "a": 30})

res = db.execute("MATCH (n:Person) RETURN n")
for row in res["rows"]:
    n = row["n"]
    if is_node(n):
        print(n["properties"]["name"])

Initialization rule:

from lora_python import Database

scratch = Database.create()            # in-memory
persistent = Database.create("app", {"database_dir": "./data"})  # persistent: ./data/app.loradb

If you want persistence, pass a database name and database_dir to Database.create(...) or Database(...).

Explain & Profile

db.explain() and db.profile() are first-class methods alongside db.execute(). They are intentionally separate calls — neither routes through execute() — so plan inspection and runtime metrics must be requested explicitly.

plan = db.explain(
    "MATCH (p:Person) WHERE p.name = $name RETURN p",
    {"name": "Alice"},
)
print(plan["shape"])             # "readOnly"
print(plan["tree"]["operator"])  # top-most operator label

profile = db.profile(
    "MATCH (p:Person) WHERE p.name = $name RETURN p",
    {"name": "Alice"},
)
print(profile["metrics"]["total_elapsed_ns"])
print(profile["metrics"]["per_operator"])  # per-step inclusive timing

explain() never invokes the executor — calling it on a mutating query (CREATE, MERGE, SET, DELETE, REMOVE) leaves the graph untouched.

profile() executes the query for real. Mutating queries produce the same side effects as execute(). Use explain() to inspect a mutating plan without running it.

Async usage (non-blocking)

import asyncio
from lora_python import AsyncDatabase

async def main():
    db = await AsyncDatabase.create()
    await db.execute("CREATE (:Person {name: 'Alice'})")
    r = await db.execute("MATCH (n:Person) RETURN n.name AS name")
    print(r["rows"])

asyncio.run(main())

Async initialization follows the same rule:

db = await AsyncDatabase.create()            # in-memory
db = await AsyncDatabase.create("app", {"database_dir": "./data"})  # persistent: ./data/app.loradb

AsyncDatabase.execute dispatches the query onto the default asyncio thread pool via asyncio.to_thread. The PyO3 Database.execute releases the Python GIL for the duration of engine work, so other coroutines on the event loop can progress while a query runs. A dedicated test proves the event loop continues ticking during a 2 000-node MATCH.

Typed value model

Same conceptual contract as lora-node / lora-wasm:

Python shape Lora value
None, bool, int, float, str scalars
list, dict collections
{"kind": "node", "id", "labels", "properties"} node
{"kind": "relationship", "id", …} relationship
{"kind": "path", "nodes": [...], "rels": [...]} path
{"kind": "date", "iso": "YYYY-MM-DD"} (and time, …) temporal
point dicts — see below point

Points are returned as dicts keyed on their CRS:

SRID Dict
7203 {"kind": "point", "srid": 7203, "crs": "cartesian", "x", "y"}
9157 {"kind": "point", "srid": 9157, "crs": "cartesian-3D", "x", "y", "z"}
4326 {"kind": "point", "srid": 4326, "crs": "WGS-84-2D", "x", "y", "longitude", "latitude"}
4979 {"kind": "point", "srid": 4979, "crs": "WGS-84-3D", "x", "y", "z", "longitude", "latitude", "height"}

Constructors and guards are exported from lora_python.types: date, time, localtime, datetime, localdatetime, duration, cartesian, cartesian_3d, wgs84, wgs84_3d, is_node, is_relationship, is_path, is_point, is_temporal.

distance() on WGS-84-3D points ignores height — see functions reference for the full spatial reference and known limitations.

Errors

  • LoraError — base class
  • LoraQueryError — parse / analyze / execute failure
  • InvalidParamsError — a parameter value couldn't be mapped

All three are available as lora_python.LoraError, etc.

Persistence

Database.create("app", {"database_dir": "./data"}), Database("app", {"database_dir": "./data"}), and await AsyncDatabase.create("app", {"database_dir": "./data"}) open or create an archive-backed persistent database at ./data/app.loradb. Reopening the same path replays committed writes before returning the handle.

Call db.close() / await db.close() before reopening the same archive inside one process.

For explicit WAL directories with managed snapshots, use open_wal:

db = Database.open_wal(
    "./data/wal",
    {
        "snapshot_dir": "./data/snapshots",
        "snapshot_every_commits": 1000,
        "snapshot_keep_old": 2,
    },
)

snapshot_options accepts the same compression/encryption options as save_snapshot.

Snapshots accept the same broad shapes in sync and async APIs:

import io
from lora_python import Database

db = Database.create()
db.execute("CREATE (:Person {name: 'Alice'})")

meta = db.save_snapshot("./graph.lorasnap")   # path / PathLike
raw = db.save_snapshot("binary")              # bytes
text = db.save_snapshot("base64")             # base64 str
buf = io.BytesIO()
meta = db.save_snapshot(buf)                  # binary writer

db.load_snapshot("./graph.lorasnap")
db.load_snapshot(raw)
db.load_snapshot(io.BytesIO(buf.getvalue()))
db.load_snapshot(text, format="base64")

Architecture

lora-database (Rust)
   └── lora-python (crate, cdylib)             <- PyO3 bindings
          ├── Database (sync, releases the GIL)
          └── python/lora_python/
                 ├── _async.py  AsyncDatabase via asyncio.to_thread
                 └── types.py   typed dicts + constructors + guards

Project details


Download files

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

Source Distribution

lora_python-0.11.3.tar.gz (694.0 kB view details)

Uploaded Source

Built Distributions

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

lora_python-0.11.3-cp38-abi3-win_amd64.whl (2.5 MB view details)

Uploaded CPython 3.8+Windows x86-64

lora_python-0.11.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (2.9 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

lora_python-0.11.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.6 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

lora_python-0.11.3-cp38-abi3-macosx_11_0_arm64.whl (2.5 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

lora_python-0.11.3-cp38-abi3-macosx_10_12_x86_64.whl (2.8 MB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file lora_python-0.11.3.tar.gz.

File metadata

  • Download URL: lora_python-0.11.3.tar.gz
  • Upload date:
  • Size: 694.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for lora_python-0.11.3.tar.gz
Algorithm Hash digest
SHA256 34b4ff1a8126a7a4edd9cd80a75abd026d6b0ce3b4a84c8413126cd528acfa10
MD5 c9a48f8c413f7b23832f8d60c8efac3f
BLAKE2b-256 28efdff5125c88d4d637d53c57b77aaefac5a4032d9b1b620bc2373facb9e77f

See more details on using hashes here.

Provenance

The following attestation bundles were made for lora_python-0.11.3.tar.gz:

Publisher: packages-release.yml on lora-db/lora

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lora_python-0.11.3-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: lora_python-0.11.3-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 2.5 MB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for lora_python-0.11.3-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 c86fe3d8cfd6306b48304a9497c02c081378f850b53412c64478f54424c9aa82
MD5 40cfd04ff50a6be1bf8ab1f7c60ba9e1
BLAKE2b-256 e08dee50ec3983d95ec46cf0dee4586662ff86d6259a779a5f6b0b38bcdb2921

See more details on using hashes here.

Provenance

The following attestation bundles were made for lora_python-0.11.3-cp38-abi3-win_amd64.whl:

Publisher: packages-release.yml on lora-db/lora

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lora_python-0.11.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for lora_python-0.11.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 df37c4f656ed5bbadcf19ab0ab08f2f5e7a3405347c18cc5467c241993f2c8ac
MD5 e863367360b574fbc39fdb4eaedd76e9
BLAKE2b-256 144e165da341ebcd78ff64c4cecf2f5348c8652da242717b889e14f3ac070a5a

See more details on using hashes here.

Provenance

The following attestation bundles were made for lora_python-0.11.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: packages-release.yml on lora-db/lora

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lora_python-0.11.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for lora_python-0.11.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c327d92eacc12973436a0e0a854d855df6ddac2438487616744d383034c42628
MD5 cd991539692101f9591e32d409090389
BLAKE2b-256 764cb5e5f4116b2c05272df03a8db77133a16514edf87c0a8bddb9412c5782db

See more details on using hashes here.

Provenance

The following attestation bundles were made for lora_python-0.11.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: packages-release.yml on lora-db/lora

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lora_python-0.11.3-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for lora_python-0.11.3-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fa7639bef050f262abd5f39d9ea580eed2b8cb2688c49cb7707a2e7b17278a95
MD5 aeaf0f2f190edde20fe2bcd038484177
BLAKE2b-256 0a277bb0747ab9af3680eabc0f1957d7885370d31087740490e19150e01fb431

See more details on using hashes here.

Provenance

The following attestation bundles were made for lora_python-0.11.3-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: packages-release.yml on lora-db/lora

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file lora_python-0.11.3-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for lora_python-0.11.3-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 1209f428c6fa8a324de49ee4fa58417af3a84cacbed8ee99e6080cdecf3971c9
MD5 9d02ee379876aee3a54adecfbc0e8a31
BLAKE2b-256 cf3963d82592792b25ecbf64fa3831747ad3910ddd123cfb5252fc35be2c51d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for lora_python-0.11.3-cp38-abi3-macosx_10_12_x86_64.whl:

Publisher: packages-release.yml on lora-db/lora

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page