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.2.tar.gz (152.5 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.2-cp310-abi3-win_amd64.whl (10.1 MB view details)

Uploaded CPython 3.10+Windows x86-64

drasi_lib-0.1.2-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.2-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.2-cp310-abi3-macosx_11_0_arm64.whl (8.9 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

drasi_lib-0.1.2-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.2.tar.gz.

File metadata

  • Download URL: drasi_lib-0.1.2.tar.gz
  • Upload date:
  • Size: 152.5 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.2.tar.gz
Algorithm Hash digest
SHA256 855aef8f03a89fc3627dbd7e9e573353c3fdb0af35de0eb6dc3c7d644de98827
MD5 4c9a20ba4e4fa4991bc32f82eb153bec
BLAKE2b-256 30754db5066a87823173f55f47ceed220a1cf4c910790dba96dd22e812ff709a

See more details on using hashes here.

Provenance

The following attestation bundles were made for drasi_lib-0.1.2.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.2-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: drasi_lib-0.1.2-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.2-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 908e58350bf244733ef4bd8ce012a10ebe7ade85330b31ed6692a07e496684aa
MD5 0197e4c34cf60aec2fd2555768f058e4
BLAKE2b-256 ab11d75ad1d949a8509d3a0a56ca8dbda5c811ef4820d59ee59d3b8e1d8e763f

See more details on using hashes here.

Provenance

The following attestation bundles were made for drasi_lib-0.1.2-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.2-cp310-abi3-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for drasi_lib-0.1.2-cp310-abi3-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 92c67d4d7cb5a778bdb44e6c43b267335d5d5c3196d62709c1fc3c6a128d84f2
MD5 39c21a8c2283e73103e67560072f2e66
BLAKE2b-256 e3ea6a0518024d9aafee6098941bf087659f7b1594f6d015a632deb250cb4b7e

See more details on using hashes here.

Provenance

The following attestation bundles were made for drasi_lib-0.1.2-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.2-cp310-abi3-manylinux_2_35_aarch64.whl.

File metadata

File hashes

Hashes for drasi_lib-0.1.2-cp310-abi3-manylinux_2_35_aarch64.whl
Algorithm Hash digest
SHA256 c3d015873efcf21add24b5ae55402b0aa4cf413f3aa267470d77f04b4ef94d55
MD5 5f5ed24f5dac8dba6ae6dd2aa3d9eebe
BLAKE2b-256 edd50df184ec98eb5f3e3c009c33324a23645c8a87ce6fa01e70744ccc512c68

See more details on using hashes here.

Provenance

The following attestation bundles were made for drasi_lib-0.1.2-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.2-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for drasi_lib-0.1.2-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0d6e668226a0d66f28b6c35df4839e6e6b644aceb2855cb468061208373d5757
MD5 7d55ed78078f75955a79c57fcf6e9365
BLAKE2b-256 d9ba331ce01e8d96041c5ea58cd65c406ee5d33da7bf10b1a138209c9f916cf5

See more details on using hashes here.

Provenance

The following attestation bundles were made for drasi_lib-0.1.2-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.2-cp310-abi3-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for drasi_lib-0.1.2-cp310-abi3-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 dc2e39fe368db9aeac9df02d718f8698b5ea29f708f96bfdb9e10bea7560303c
MD5 154acc3b4b32bf61dffdabf84de0848d
BLAKE2b-256 81dce9015bbbd3b5a4d37579727870dac0e2860da9c325fc07076fc5a34497ef

See more details on using hashes here.

Provenance

The following attestation bundles were made for drasi_lib-0.1.2-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