Skip to main content

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.
  • Streamingasync for event in drasi.query_results(id), plus lifecycle events and component logs.
  • A blocking APIdrasi.sync.Drasi for scripts and notebooks.

Status: pre-1.0. The API is complete — full parity with @drasi/lib plus streaming as async iterators, a blocking facade, and plugin lockfiles. See docs/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 calling start() also works, but logs a spurious "already running" error for each component.
  • Drasi's Cypher dialect uses single-quoted string literals.
  • A change's id is the graph key, not a property. A query selecting o.id reads 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

drasi_lib-0.1.1.tar.gz (149.8 kB view details)

Uploaded Source

Built Distributions

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

drasi_lib-0.1.1-cp310-abi3-win_amd64.whl (10.1 MB view details)

Uploaded CPython 3.10+Windows x86-64

drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_x86_64.whl (10.6 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.35+ x86-64

drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_aarch64.whl (10.0 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.35+ ARM64

drasi_lib-0.1.1-cp310-abi3-macosx_11_0_arm64.whl (8.9 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

drasi_lib-0.1.1-cp310-abi3-macosx_10_13_x86_64.whl (9.6 MB view details)

Uploaded CPython 3.10+macOS 10.13+ x86-64

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

Hashes for drasi_lib-0.1.1.tar.gz
Algorithm Hash digest
SHA256 5c31b481b5d446377807ff516c2011903719834a95385a0fe9727c269190fe79
MD5 0d0858af2bcb33be441f86c72d72e6d4
BLAKE2b-256 8715d61aa5e9a542f6b26025976d94f8c7be30e54e33493de1d78a0ff655ee31

See more details on using hashes here.

Provenance

The following attestation bundles were made for drasi_lib-0.1.1.tar.gz:

Publisher: release.yml on drasi-project/drasi-python

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

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

Hashes for drasi_lib-0.1.1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 fd331ecdf23d145bfcab9889de1e5365f77ea08f8453dd4431491332ff80080d
MD5 ea0da4e476e16c35efe14ced1a906fda
BLAKE2b-256 330d139ece5eae51a5c19208e62d6a7e92f3fe3287831490d4215e1290bbdb81

See more details on using hashes here.

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

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

File details

Details for the file drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 dd1bf3485861cb8f2161e290947ecd73d32ace751586e2db213749ea7e2ba3e9
MD5 51390ea12dd76024c87296bf5c335191
BLAKE2b-256 2a08c485dfd27c1c5f11fc25f0017b42cd10c3dc9c81d09868194abe51d89f3c

See more details on using hashes here.

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

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

File details

Details for the file drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_aarch64.whl.

File metadata

File hashes

Hashes for drasi_lib-0.1.1-cp310-abi3-manylinux_2_35_aarch64.whl
Algorithm Hash digest
SHA256 14a353ed962528efd07140cec781aee261cd30d5f855e69174ca80e2d988c44a
MD5 3098e2d4ef4f2899aaac63f259416c16
BLAKE2b-256 c450e8a945087a829630b9fcd815f5e3d0b099fe08793f733cdd6d627a998d2f

See more details on using hashes here.

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

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

File details

Details for the file drasi_lib-0.1.1-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for drasi_lib-0.1.1-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 7a466f9327e09544da873cf0ba7f46c0f5ce2f781bbbb4ea0579f6a5f6a31ce2
MD5 d3576a1cc3f8e5a780bb5f0d8143f723
BLAKE2b-256 dcc868801278aeab93837e1eba3393548ff0fc3f7dfbced955d3ecb9d51cd8d6

See more details on using hashes here.

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

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

File details

Details for the file drasi_lib-0.1.1-cp310-abi3-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for drasi_lib-0.1.1-cp310-abi3-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 c447d3f0e1db7698a59089f93746d8ef5af20db57b5a2206d5dbdc64c2abc824
MD5 9e3d3083896c95ce5e9c2e78ff29e13c
BLAKE2b-256 f1cb1d47a8eae8b4fe5fd54818f7f876929566bd5be75d9f67cb41af18f29edb

See more details on using hashes here.

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

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