Embed the Drasi continuous-query engine directly in your Python application
Project description
drasi-lib
Embed the Drasi continuous-query engine directly in your
Python application. drasi-lib is a native PyO3 binding
around Drasi's embeddable engine (drasi-lib) and its plugin host SDK
(drasi-host-sdk), so you get:
- In-process continuous queries over a property graph, in Cypher or GQL.
- A working plugin ecosystem — search, resolve, download, verify and install
the Drasi source/reaction/bootstrap plugins published to
ghcr.io/drasi-project, picking the build that is compatible with your host. - Python-defined components — define a reaction as a Python callback, or a source you push changes into from your own code. No Rust required.
- Streaming —
async for event in drasi.query_results(id), plus lifecycle events and component logs. - A blocking API —
drasi.sync.Drasifor scripts and notebooks.
Status: pre-1.0. The API is complete — full parity with
@drasi/libplus streaming as async iterators, a blocking facade, and plugin lockfiles. Seedocs/api-audit.md.
Install
pip install drasi-lib
Imported as drasi. Wheels are abi3 for Python 3.10+ on Linux (x86_64,
aarch64), macOS (x86_64, arm64) and Windows (x86_64), so no Rust toolchain is
needed. To build from source instead, see Development, or
examples/README.md for a step-by-step walkthrough.
Quickstart
Push changes from your own code and react to the results — no plugins needed:
import asyncio
from drasi import Drasi
async def main() -> None:
async with await Drasi.create("my-app") as drasi:
await drasi.start()
await drasi.add_python_source("orders")
await drasi.add_query(
"open",
"MATCH (o:Order) WHERE o.status = 'open' RETURN o.id AS id, o.total AS total",
["orders"],
)
def on_results(event):
for diff in event["results"]:
print(diff["type"], diff.get("data"))
await drasi.add_python_reaction("watch", ["open"], on_results)
await drasi.push_change(
"orders",
{
"op": "insert",
"id": "o1",
"labels": ["Order"],
"properties": {"id": "o1", "status": "open", "total": 42},
},
)
await asyncio.sleep(0.5)
print(await drasi.get_query_results("open"))
asyncio.run(main())
Three things that are easy to get wrong:
- Call
start()first, then add components; they auto-start individually. Adding everything and then callingstart()also works, but logs a spurious "already running" error for each component. - Drasi's Cypher dialect uses single-quoted string literals.
- A change's
idis the graph key, not a property. A query selectingo.idreads a property of that name, so emit it explicitly.
add_query returns once the query is provisioned; it finishes starting in the
background, so reading results immediately can raise "is not running". Await
wait_for_query(id) if you need to read straight away.
Using a plugin
install_plugin() resolves the build that is compatible with your machine,
downloads it, verifies it and loads it:
async with await Drasi.create("my-app") as drasi:
await drasi.install_plugin("source/mock")
await drasi.start()
await drasi.add_source("mock", "counters", {"dataType": {"type": "counter"}, "intervalMs": 500})
await drasi.add_query("counts", "MATCH (c:Counter) RETURN c.value AS value", ["counters"])
Browse what is available first, if you like:
for plugin in await drasi.search_plugins():
print(plugin["reference"]) # e.g. source/postgres, reaction/http
Plugin configuration keys are defined by the plugin itself, so they are passed
through untouched — dataType above is the mock source's own spelling. Drasi's
own API is snake_case, and accepts the Node.js camelCase spellings as aliases.
Plugins
Drasi plugins are self-contained cdylib files distributed as OCI artifacts
from ghcr.io/drasi-project, published per platform:
ghcr.io/drasi-project/{type}/{kind}:{version}-{arch}
Because a plugin is a native library loaded into your process, it is only usable
by a host built against a compatible set of Drasi crates. install_plugin()
handles this for you — it reads the registry index, picks the newest build whose
sdk/core/lib versions and target triple match this host, downloads it,
optionally verifies its cosign signature, and loads it.
See docs/plugins.md.
Watching a query
Polling is rarely what you want:
async for event in await drasi.query_results("open"):
for diff in event["results"]:
print(diff["type"], diff.get("data"))
Lifecycle events (query_events, source_events, reaction_events,
all_events) and logs (query_logs, source_logs, reaction_logs) stream the
same way, and replay their history first. Callback forms (on_query_results,
on_*_events, on_*_logs) exist for parity with the Node.js binding.
Without async
from drasi.sync import Drasi
with Drasi.create("my-app") as drasi:
drasi.start()
drasi.add_python_source("orders")
print(drasi.get_query_results("open"))
Streams become ordinary iterators. Don't use this inside an existing event loop — it will tell you so rather than deadlocking.
Durability
A durable reaction only advances its checkpoint once your callback succeeds, so an unhandled event is replayed after a restart:
drasi = await Drasi.create("app", state_store={"kind": "redb", "path": "state.redb"})
async def handle(event):
await write_somewhere(event) # if this raises, the event is retried
await drasi.add_durable_python_reaction("sink", ["open"], handle)
Status
docs/api-audit.md inventories the public API and
compares it against the Node.js bindings and the Rust engine. It is at full
parity — 48/48 methods — plus 21 methods Node does not have.
Examples
Runnable programs are in examples/, with a guide covering how to
build the package locally and run them:
| Example | What it shows | Needs |
|---|---|---|
python_source.py |
Push changes from your own code; react to results | nothing |
install_plugin.py |
Browse the registry, install a plugin, use it | network |
postgres_cdc.py |
React to a real Postgres database | Docker, network |
make venv && make develop
.venv/bin/python examples/python_source.py
Development
make venv # create .venv with a managed Python and the dev tooling
make develop # build the native extension and install it editable
make test # unit tests + hermetic end-to-end tests
make test-oci # download and install real plugins from ghcr.io
Building requires a Rust toolchain. The optional rocksdb feature additionally
requires libclang and a C++ toolchain. See CONTRIBUTING.md.
License
Apache-2.0. See LICENSE.
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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file drasi_lib-0.1.1.tar.gz.
File metadata
- Download URL: drasi_lib-0.1.1.tar.gz
- Upload date:
- Size: 149.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c31b481b5d446377807ff516c2011903719834a95385a0fe9727c269190fe79
|
|
| MD5 |
0d0858af2bcb33be441f86c72d72e6d4
|
|
| BLAKE2b-256 |
8715d61aa5e9a542f6b26025976d94f8c7be30e54e33493de1d78a0ff655ee31
|
Provenance
The following attestation bundles were made for drasi_lib-0.1.1.tar.gz:
Publisher:
release.yml on drasi-project/drasi-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
drasi_lib-0.1.1.tar.gz -
Subject digest:
5c31b481b5d446377807ff516c2011903719834a95385a0fe9727c269190fe79 - Sigstore transparency entry: 2276995763
- Sigstore integration time:
-
Permalink:
drasi-project/drasi-python@1c60a8a7adabe5f65551582e84151553853baf3c -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/drasi-project
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1c60a8a7adabe5f65551582e84151553853baf3c -
Trigger Event:
push
-
Statement type:
File details
Details for the file drasi_lib-0.1.1-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: drasi_lib-0.1.1-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 10.1 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd331ecdf23d145bfcab9889de1e5365f77ea08f8453dd4431491332ff80080d
|
|
| MD5 |
ea0da4e476e16c35efe14ced1a906fda
|
|
| BLAKE2b-256 |
330d139ece5eae51a5c19208e62d6a7e92f3fe3287831490d4215e1290bbdb81
|
Provenance
The following attestation bundles were made for drasi_lib-0.1.1-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on drasi-project/drasi-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
drasi_lib-0.1.1-cp310-abi3-win_amd64.whl -
Subject digest:
fd331ecdf23d145bfcab9889de1e5365f77ea08f8453dd4431491332ff80080d - Sigstore transparency entry: 2276995792
- Sigstore integration time:
-
Permalink:
drasi-project/drasi-python@1c60a8a7adabe5f65551582e84151553853baf3c -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/drasi-project
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1c60a8a7adabe5f65551582e84151553853baf3c -
Trigger Event:
push
-
Statement type:
File details
Details for the file drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_x86_64.whl.
File metadata
- Download URL: drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_x86_64.whl
- Upload date:
- Size: 10.6 MB
- Tags: CPython 3.10+, manylinux: glibc 2.35+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dd1bf3485861cb8f2161e290947ecd73d32ace751586e2db213749ea7e2ba3e9
|
|
| MD5 |
51390ea12dd76024c87296bf5c335191
|
|
| BLAKE2b-256 |
2a08c485dfd27c1c5f11fc25f0017b42cd10c3dc9c81d09868194abe51d89f3c
|
Provenance
The following attestation bundles were made for drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_x86_64.whl:
Publisher:
release.yml on drasi-project/drasi-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_x86_64.whl -
Subject digest:
dd1bf3485861cb8f2161e290947ecd73d32ace751586e2db213749ea7e2ba3e9 - Sigstore transparency entry: 2276995932
- Sigstore integration time:
-
Permalink:
drasi-project/drasi-python@1c60a8a7adabe5f65551582e84151553853baf3c -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/drasi-project
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1c60a8a7adabe5f65551582e84151553853baf3c -
Trigger Event:
push
-
Statement type:
File details
Details for the file drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_aarch64.whl.
File metadata
- Download URL: drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_aarch64.whl
- Upload date:
- Size: 10.0 MB
- Tags: CPython 3.10+, manylinux: glibc 2.35+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14a353ed962528efd07140cec781aee261cd30d5f855e69174ca80e2d988c44a
|
|
| MD5 |
3098e2d4ef4f2899aaac63f259416c16
|
|
| BLAKE2b-256 |
c450e8a945087a829630b9fcd815f5e3d0b099fe08793f733cdd6d627a998d2f
|
Provenance
The following attestation bundles were made for drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_aarch64.whl:
Publisher:
release.yml on drasi-project/drasi-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_aarch64.whl -
Subject digest:
14a353ed962528efd07140cec781aee261cd30d5f855e69174ca80e2d988c44a - Sigstore transparency entry: 2276995896
- Sigstore integration time:
-
Permalink:
drasi-project/drasi-python@1c60a8a7adabe5f65551582e84151553853baf3c -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/drasi-project
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1c60a8a7adabe5f65551582e84151553853baf3c -
Trigger Event:
push
-
Statement type:
File details
Details for the file drasi_lib-0.1.1-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: drasi_lib-0.1.1-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 8.9 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a466f9327e09544da873cf0ba7f46c0f5ce2f781bbbb4ea0579f6a5f6a31ce2
|
|
| MD5 |
d3576a1cc3f8e5a780bb5f0d8143f723
|
|
| BLAKE2b-256 |
dcc868801278aeab93837e1eba3393548ff0fc3f7dfbced955d3ecb9d51cd8d6
|
Provenance
The following attestation bundles were made for drasi_lib-0.1.1-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on drasi-project/drasi-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
drasi_lib-0.1.1-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
7a466f9327e09544da873cf0ba7f46c0f5ce2f781bbbb4ea0579f6a5f6a31ce2 - Sigstore transparency entry: 2276995828
- Sigstore integration time:
-
Permalink:
drasi-project/drasi-python@1c60a8a7adabe5f65551582e84151553853baf3c -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/drasi-project
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1c60a8a7adabe5f65551582e84151553853baf3c -
Trigger Event:
push
-
Statement type:
File details
Details for the file drasi_lib-0.1.1-cp310-abi3-macosx_10_13_x86_64.whl.
File metadata
- Download URL: drasi_lib-0.1.1-cp310-abi3-macosx_10_13_x86_64.whl
- Upload date:
- Size: 9.6 MB
- Tags: CPython 3.10+, macOS 10.13+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c447d3f0e1db7698a59089f93746d8ef5af20db57b5a2206d5dbdc64c2abc824
|
|
| MD5 |
9e3d3083896c95ce5e9c2e78ff29e13c
|
|
| BLAKE2b-256 |
f1cb1d47a8eae8b4fe5fd54818f7f876929566bd5be75d9f67cb41af18f29edb
|
Provenance
The following attestation bundles were made for drasi_lib-0.1.1-cp310-abi3-macosx_10_13_x86_64.whl:
Publisher:
release.yml on drasi-project/drasi-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
drasi_lib-0.1.1-cp310-abi3-macosx_10_13_x86_64.whl -
Subject digest:
c447d3f0e1db7698a59089f93746d8ef5af20db57b5a2206d5dbdc64c2abc824 - Sigstore transparency entry: 2276995857
- Sigstore integration time:
-
Permalink:
drasi-project/drasi-python@1c60a8a7adabe5f65551582e84151553853baf3c -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/drasi-project
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1c60a8a7adabe5f65551582e84151553853baf3c -
Trigger Event:
push
-
Statement type: