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 asexecute(). Useexplain()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()andtransaction([...])take the lock, run, commit and release it within one call on one thread. OnAsyncDatabasethey 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 theDatabaseit came from.AsyncDatabase.streamnever 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 usetransaction([...]).
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 ignoresheight— see functions reference for the full spatial reference and known limitations.
Errors
LoraError— base classLoraQueryError— parse / analyze / execute failureInvalidParamsError— 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.22.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| lora_python-0.22.3.tar.gz | 996.2 kB | With provenance | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| lora_python-0.22.3-cp38-abi3-win_amd64.whl | CPython 3.8 | abi3 | Windows x86-64 | Details |
| lora_python-0.22.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| lora_python-0.22.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| lora_python-0.22.3-cp38-abi3-macosx_11_0_arm64.whl | CPython 3.8 | abi3 | macOS 11.0+ ARM64 | Details |
| lora_python-0.22.3-cp38-abi3-macosx_10_12_x86_64.whl | CPython 3.8 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 16.8 MB
Release files / lora_python-0.22.3.tar.gz
| Download URL | lora_python-0.22.3.tar.gz |
|---|---|
| Size | 996.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c3af7027abf5cbecb0c9cf57a49b9c645343258eee2aad34b0eba7f75716fdfc
|
|
BLAKE2b-256 checksum How to use checksums |
dc250a1d1344dbf9bdd9862a204c9b94ef3abebd1012e167f93c4c0dea30414a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 5, 2026.
Transparency logRelease files / lora_python-0.22.3-cp38-abi3-win_amd64.whl
| Download URL | lora_python-0.22.3-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 3.0 MB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
c53c69008e7129241cf9b88650fa003102592b40cbae62c262751db0e44981d5
|
|
BLAKE2b-256 checksum How to use checksums |
b49b44992f063387e32932c85bca5189d8494e6eaaa0daa22ad769f31d97ee9d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 5, 2026.
Transparency logRelease files / lora_python-0.22.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | lora_python-0.22.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 3.4 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
d1eddf152d4661e95df66ae3d28d292284fd7e0fb005c2abcf618333633522f3
|
|
BLAKE2b-256 checksum How to use checksums |
d34db12ca817ff83666f80075c8ea35835a4e2ca23ca3a29f4e4d53df4eba0dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 5, 2026.
Transparency logRelease files / lora_python-0.22.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | lora_python-0.22.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 3.1 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
47ce008b3f5475cfd59f5a9caa938438019d0736e2f671eb62f6650f8abed80d
|
|
BLAKE2b-256 checksum How to use checksums |
940aecf0216dacd972db52ef852c2879ed2893cc56c2e6a28192e21211594372
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 5, 2026.
Transparency logRelease files / lora_python-0.22.3-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | lora_python-0.22.3-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.9 MB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
86bd379fc9493221e1dd22de2f50f0b124230eb9cffbf27a2f0336ad049fe698
|
|
BLAKE2b-256 checksum How to use checksums |
dda327d537ca113c4dd8992533a69813ac47d9e1e7d8144b20a2623314ae9d73
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 5, 2026.
Transparency logRelease files / lora_python-0.22.3-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | lora_python-0.22.3-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 3.3 MB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
a2dc4425fd2573e3571e149daecdc475b3abf69fad29d150de66ee005c150865
|
|
BLAKE2b-256 checksum How to use checksums |
76c19dce5137defcf93d18c2407f6e9cf185cd480767217c6b4776b3b6924e9e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 5, 2026.
Transparency logSecurity for lora-python 0.22.3
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.
Attestation for lora_python-0.22.3.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 5, 2026.
Transparency logA 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.