Drasi

Integrations for Drasi

The Drasi extension in Dapr Agents enables DurableAgent runs to be triggered by Drasi events.

Why Use Drasi?

Many systems need to react to changes produced by other systems in near real-time. Traditional polling cannot detect the absence of change, or changes that occur at an extremely high frequency without unnecessary load on source systems (even without considering network delay). Raw changes are usually not actionable, requiring custom change data capture (CDC) pipelines to process changes at scale and convert them into meaningful domain events. However, these pipelines can be expensive (if managed) or difficult to set up and maintain (if self-hosted).

For many use cases, Drasi is a viable alternative. Drasi is a CNCF Sandbox project that addresses the issues mentioned above with a simple architecture centered around detecting and reacting to changes:

  • Sources to ingest changes from existing systems
  • Queries allowing high-level “business conditions” to be defined across a variety of data sources, which emit events when those conditions are satisfied
  • Reactions to push events to downstream consumers

Installation

pip install "dapr-agents[drasi]"
uv add dapr-agents[drasi]

Usage

from dapr_agents import AgentRunner, DurableAgent
from dapr_agents.agents.configs import AgentPubSubConfig

from dapr_agents.ext.drasi import drasi_trigger

agent = DurableAgent(
    name="InventoryAgent",
    pubsub=AgentPubSubConfig(
        pubsub_name="pubsub",           # Replace with your pub/sub component
        agent_topic="inventory-agent",  # Replace with your agent pub/sub topic
    ),
)

drasi_trigger(
    agent,
    query_id="low-stock-products",      # Replace with your Drasi query ID
)

AgentRunner().serve(agent)

API

drasi_trigger

drasi_trigger creates a static subscription to a Drasi query and allows agents to be triggered by Drasi events via Dapr pub/sub.

Parameters

ParameterTypeRequiredDetailsExample
agentDurableAgentYThe target agent.N/A
query_idstrYThe Drasi query ID to subscribe to."low-stock-products"
pubsubstrNThe name of the Dapr pub/sub component to use. Defaults to the agent’s pub/sub component."pubsub"
topicstrNThe topic to subscribe to. Defaults to "drasi-events-" + query_id.N/A
dead_letter_topicstrNDead-letter topic to publish failed messages to."low-stock-events-dlq"
task_mapperCallable[[DrasiChangeEvent, MessageContext], TriggerAction]NCallable to map Drasi change events to agent task messages. Defaults to instructing the agent to return the serialized Drasi event as-is.N/A
operationsDrasiOperation | str | list[DrasiOperation | str]NDrasi operation(s) to filter change events by. Accepts DrasiOperation or equivalent string literals.N/A
change_modeltype[Any]NModel to use to validate the change data in Drasi events.N/A

DrasiOperation

DrasiOperation is an enum representing the supported Drasi change operations.

Operations

OperationValueDetails
DrasiOperation.i"i"A record was added to the result set tracked by the Drasi query.
DrasiOperation.u"u"A record was updated in the result set tracked by the Drasi query.
DrasiOperation.d"d"A record was deleted from the result set tracked by the Drasi query.

DrasiChangeEvent

DrasiChangeEvent is a Pydantic model representing a change event emitted by a query.

Attributes

AttributeTypeRequiredDetailsExample
opDrasiOperationYThe change event operation (insert, update, delete).DrasiOperation.u
ts_msintYThe timestamp of the change event in milliseconds.42
seqintYThe sequence number of the change event.1
payloaddict[str, Any]YThe change data for the change event.{"source": {"queryId": "low-stock-products", "ts_ms": 42}, "before": {"a": 1}, "after": {"a": 2}}

Example Structure

{
    "op": "u",
    "ts_ms": 42,
    "seq": 1,
    "payload": {
        "source": {
            "queryId": "low-stock-products",
            "ts_ms": 42
        },
        "before": {"a": 1},
        "after": {"a": 2}
    }
}

Examples

See the Extension Examples for a list of working examples for the Drasi extension.