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())

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.3.tar.gz (215.7 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.3-cp310-abi3-win_amd64.whl (10.2 MB view details)

Uploaded CPython 3.10+Windows x86-64

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

Uploaded CPython 3.10+macOS 11.0+ ARM64

drasi_lib-0.1.3-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.3.tar.gz.

File metadata

  • Download URL: drasi_lib-0.1.3.tar.gz
  • Upload date:
  • Size: 215.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for drasi_lib-0.1.3.tar.gz
Algorithm Hash digest
SHA256 b7e07041f4e475f522ed44d9133a353d33ae71f5ba5b18b36706b89f2dc38445
MD5 28d86aeb8d695c6eb7b3f0d9ba4f697d
BLAKE2b-256 0d1898b5b03db3b46504a2de3356e54ee009c03045cb84ebde1b54851d3b836e

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: drasi_lib-0.1.3-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 10.2 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for drasi_lib-0.1.3-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 ba9b88cd422d3d0552e0d7b673a01cca869613392704e2a4da0e9eef4fae83e1
MD5 929d1e0cfa65f09582b744815bdcc356
BLAKE2b-256 72370190c4a527f1f45a8ca2cb27377d4d9e664aadcf86bcd6e7c37d4441f51f

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for drasi_lib-0.1.3-cp310-abi3-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 3940bc15d8141681da67135f15a4ae8700973d70a8ce31a10f644fd79e165391
MD5 f53941c515a6f80038fa94326ceff52b
BLAKE2b-256 79f0775650e82c3c157add5d31b5c3016609956fddfe2ed572cf551b34ad0bee

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for drasi_lib-0.1.3-cp310-abi3-manylinux_2_35_aarch64.whl
Algorithm Hash digest
SHA256 3d3b882aed21a6f0c2d1786a2db43dc470d18c98afed6aab019ea4330d628ca7
MD5 43d5f7eb15c4ce06517be7e21770afbf
BLAKE2b-256 2c2c8e0519ce3216233859024317e5600677ac26a8d172ef5cd1924f2560cc10

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for drasi_lib-0.1.3-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e4166efe849c6939a3d5213978fddabeec214f8e11c2d13f4daa9e9836a428c4
MD5 dcf434723cfcbaa3c256c7001a7b50fe
BLAKE2b-256 b90a9e68b6b928258f62eba4eda21a775bb7e5e8ade12fb8979aee18e0a1292c

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for drasi_lib-0.1.3-cp310-abi3-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 c877a7eb6f443300c1f078f20e2bd527616d130bc62038df74d9974d21a23a02
MD5 7e401e6796bf6113894c01196312ae98
BLAKE2b-256 816362c84f4af1f89c4738890dd5ad0613458e8f3985caef9039e86d4703cd05

See more details on using hashes here.

Provenance

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