Skip to main content

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.

Concurrency, transactions and streams

Writers serialize on the database's writer lock; readers never wait for it. Every call that may wait for the lock (execute, transaction, clear, load_snapshot, opening a stream) waits with the GIL released, so the thread holding the lock always keeps running.

  • execute() and transaction([...]) take the lock, run, commit and release it within one call on one thread. On AsyncDatabase they run on the loop's default executor; a small or saturated executor delays writes but cannot deadlock them, since the writer holding the lock never needs an executor thread to finish.
  • A mutating stream() (one whose query writes) holds the writer lock from open until it is exhausted (commit) or closed early (rollback). It runs on a native thread of its own, so a stream can be pulled, closed or garbage-collected on any thread, and may outlive the Database it came from. AsyncDatabase.stream never waits for the lock on the event loop: a stream that does not get it at once finishes opening on a thread of its own. It pulls one row per iteration step.
  • While your own code holds a mutating stream open, do not wait on another write to the same database from that same thread or coroutine: that write waits for the lock your stream holds. On AsyncDatabase, avoid awaiting other database calls inside the loop body of a mutating stream when many writers may be queued on the executor; collect the rows first, or use transaction([...]).

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

Metadata

Release files for lora-python 0.33.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 lora-python 0.33.0
File Size Uploaded Provenance Actions
lora_python-0.33.0.tar.gz 1.3 MB With provenance Details for lora_python-0.33.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for lora-python 0.33.0
File Actions
lora_python-0.33.0-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details for lora_python-0.33.0-cp38-abi3-win_amd64.whl
lora_python-0.33.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details for lora_python-0.33.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
lora_python-0.33.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details for lora_python-0.33.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
lora_python-0.33.0-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details for lora_python-0.33.0-cp38-abi3-macosx_11_0_arm64.whl
lora_python-0.33.0-cp38-abi3-macosx_10_12_x86_64.whl CPython 3.8 abi3 macOS 10.12+ x86-64 Details for lora_python-0.33.0-cp38-abi3-macosx_10_12_x86_64.whl

Total release size: 22.9 MB

Release files / lora_python-0.33.0.tar.gz

Download URL lora_python-0.33.0.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
48e68ad5d0e7236b2b13d821a000c10055efe537e73558f2da8cd922a0c9d7a6
BLAKE2b-256 checksum
How to use checksums
4163f6131cd32a1834f8fd9578dd1cc26aedbf81e65c8ffc42ec5159e6f6cce7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / lora_python-0.33.0-cp38-abi3-win_amd64.whl

Download URL lora_python-0.33.0-cp38-abi3-win_amd64.whl
Size 4.5 MB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
2972d61590b6e7a34e2de6ddb8220f733a8757845f0f84be061cc86cf1e76ca1
BLAKE2b-256 checksum
How to use checksums
62cd2c0468b12b002ae4bfd4bafdbd63a28641def5f0ade67ff8f0d635aff833
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / lora_python-0.33.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL lora_python-0.33.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 4.5 MB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
37327f16124071116a8af459aa6a5c65eea489942ad4546cb71f7c601f0b4c49
BLAKE2b-256 checksum
How to use checksums
05f954dd876c0a119546026926d1359fd3d7a7395eea25659b02bdc247088ce0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / lora_python-0.33.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL lora_python-0.33.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 4.2 MB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
255cda654cb8794e392ae093bb9b0c036f0530b128c96b3f935a821680c49148
BLAKE2b-256 checksum
How to use checksums
db63e963f44389a8e7faf759cca516c8ac2b248ef42f14fefb086c5199e8f95e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / lora_python-0.33.0-cp38-abi3-macosx_11_0_arm64.whl

Download URL lora_python-0.33.0-cp38-abi3-macosx_11_0_arm64.whl
Size 4.1 MB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
5f98ed454955f74f7dc5c5e624b340ec6ae6a80210b973eec35ac2737b7a1aa5
BLAKE2b-256 checksum
How to use checksums
b998b51dde453461c339750dd9214e6f02b518b2545be402d90c5980d8b9e328
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / lora_python-0.33.0-cp38-abi3-macosx_10_12_x86_64.whl

Download URL lora_python-0.33.0-cp38-abi3-macosx_10_12_x86_64.whl
Size 4.4 MB
Tags CPython 3.8 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
f0e3387e2aec2174a5f1a1d494fd3fc3f7e45c6f6e75650e37dd8533a22560fc
BLAKE2b-256 checksum
How to use checksums
df742f70d88571f0b75937e6748ab12da2ea9cea23245caf8a0adc92f36ffd1d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Security for lora-python 0.33.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.

Full provenance

All 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for lora_python-0.33.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

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.

Release history Release notifications | RSS feed

This release

0.33.0 This release

6 release files Full provenance

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