Getting Started
3 minute read
Install
pip install drasi-lib
The distribution is named drasi-lib and imported as drasi:
import drasi
Wheels are abi3 for Python 3.10 and newer, published for Linux (x86_64, aarch64), macOS (x86_64, arm64) and Windows (x86_64). One wheel per platform covers every supported Python version, and no Rust toolchain is needed to install.
Your first continuous query
This pushes changes into a Python-defined source and prints each way the result set changes. It needs nothing but the package:
import asyncio
from drasi import Drasi
OPEN_ORDERS = """
MATCH (o:Order)
WHERE o.status = 'open'
RETURN o.id AS id, o.total AS total
"""
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", OPEN_ORDERS, ["orders"])
def on_results(event):
for diff in event["results"]:
print(diff["type"], diff.get("data") or diff.get("after"))
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(1)
print(await drasi.get_query_results("open"))
asyncio.run(main())
Running it prints an ADD diff as the order enters the result set, then the current
result set.
What each piece does
Drasi.create(...)builds an engine. Used as anasync with, it closes for you.start()starts the engine and every component set to auto-start.add_python_source(...)registers a source you push changes into from your own code. For real systems, load a plugin instead.add_query(...)registers a continuous query. It re-evaluates incrementally as changes arrive, rather than re-running over the whole dataset.add_python_reaction(...)receives the diffs — what was added, updated and removed — as the result set changes.
Ordering
Adding components before start() and after it both work. The example above starts
first, which is the pattern used throughout these docs.
Not using asyncio?
Every method has a blocking counterpart in drasi.sync, for scripts, notebooks and
anywhere async would be awkward:
import time
from drasi.sync import Drasi
OPEN_ORDERS = """
MATCH (o:Order)
WHERE o.status = 'open'
RETURN o.id AS id, o.total AS total
"""
with Drasi.create("script") as drasi:
drasi.start()
drasi.add_python_source("orders")
drasi.add_query("open", OPEN_ORDERS, ["orders"])
drasi.push_change(
"orders",
{
"op": "insert",
"id": "o1",
"labels": ["Order"],
"properties": {"id": "o1", "status": "open", "total": 42},
},
)
# A query processes changes asynchronously, so give it a moment before
# reading the result set. `query_results` is the alternative: it yields each
# change as it lands rather than making you guess how long to wait.
time.sleep(1)
print(drasi.get_query_results("open"))
See the blocking API for the details.
Connecting to a real system
Python-defined sources are the quickest way to see the engine work, but most
applications follow an existing system. Drasi publishes source, reaction and
bootstrap plugins to ghcr.io/drasi-project, and drasi-lib can resolve, download,
verify and load them at runtime:
await drasi.install_plugin("source/postgres")
await drasi.install_plugin("bootstrap/postgres")
await drasi.start()
await drasi.add_source(
"postgres",
"db",
{
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "app",
"tables": ["public.orders"],
"tableKeys": [{"table": "orders", "keyColumns": ["id"]}],
},
bootstrap={
"kind": "postgres",
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "postgres",
"database": "app",
},
)
The plugins guide covers searching the registry, pinning versions, signature verification and lockfiles. The Postgres dashboard example puts the whole thing together.
Next
- Concepts — how the change-driven model fits together.
- Guides — sources, reactions, plugins, streaming and errors.
- API reference — every method, grouped by area.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.