Skip to content

Core Concepts

PyRapide models systems as causal event-driven architectures, collections of components that communicate through events linked by cause-and-effect relationships. This page provides a map of the foundational concepts you will use when building with PyRapide.

💡 Tip

New to PyRapide? Start with the Getting Started guide for a hands-on walkthrough, then return here for deeper understanding.


Events and Causal History

An event is the atomic unit of observation in PyRapide. Every event records what happened, when it happened, and, critically, why it happened. Events carry a causal history: the set of predecessor events that directly or transitively caused them. This history is what separates PyRapide from flat, timestamp-ordered logging systems.

events_intro.py python
from pyrapide import Event

# Every event knows its causal ancestors
event = computation.events[0]
print(event.causes)      # direct causes
print(event.history())   # full transitive causal history

Read the full Events documentation →


Posets: Partially Ordered Event Sets

When multiple components emit events concurrently, there is no single "correct" ordering. PyRapide represents the result of an execution as a poset (partially ordered set): a directed acyclic graph where edges encode causal precedence. Two events are ordered only if one causally depends on the other; otherwise they are concurrent.

Posets give you the mathematical structure needed for root-cause analysis, impact assessment, and concurrency reasoning without imposing an artificial total order on inherently concurrent events.

Read the full Posets documentation →


Computations

A computation is the complete causal event graph produced by a single execution of an architecture. It is the queryable artifact that PyRapide's analysis tools operate on. You can slice it, search it, check constraints against it, and serialize it for later review.

computation_query.py python
computation = await engine.run()

# Query the computation
print(len(computation.events))
print(computation.root_causes(some_event))
print(computation.forward_slice(some_event))

Read the full Computations documentation →


Interfaces and Actions

An interface declares the behavioral contract of a component: what actions it can perform and what event types those actions produce. Interfaces are abstract; they specify what a component does without prescribing how.

Each method on an interface decorated with @action becomes a typed action that generates traceable events when invoked.

interfaces.py python
from pyrapide import interface, action

@interface
class Sensor:
    @action
    async def reading(self, temperature: float) -> None: ...

@interface
class Alerter:
    @action
    async def alert(self, message: str, severity: str) -> None: ...

Read the full Interfaces documentation →


Modules

A module is the concrete implementation of an interface. It contains the actual logic (reading sensors, calling APIs, sending alerts) while conforming to the interface's behavioral contract. Modules are where your application code lives.

modules.py python
from pyrapide import module

@module(implements=Sensor)
class TemperatureSensor:
    async def reading(self, temperature: float) -> None:
        print(f"Sensor recorded {temperature}°C")

Read the full Modules documentation →


Architectures and Connections

An architecture composes modules into a system by declaring which components exist and how events flow between them. Connections define the wiring: when a pattern of events is observed on one component, matching events are routed to another.

PyRapide supports three causal connection semantics: pipe (sequential), broadcast (fan-out), and filter (conditional routing).

architecture.py python
from pyrapide import architecture, connect, Pattern

@architecture
class MonitoringSystem:
    sensor: Sensor
    alerter: Alerter

    def connections(self):
        return [connect(Pattern.match("Sensor.reading"), "alerter")]

Read the full Architectures documentation →


Event Patterns

Patterns are declarative expressions that match against event streams. They power connections (routing events between components) and constraints (specifying behavioral rules). PyRapide provides pattern combinators for matching by action name, attribute values, sequences, and causal relationships.

patterns.py python
from pyrapide import Pattern

# Match any reading above a threshold
high_temp = Pattern.match("Sensor.reading", temperature=lambda t: t > 100)

# Match a sequence: reading followed by alert
sequence = Pattern.seq("Sensor.reading", "Alerter.alert")

Read the full Patterns documentation →


Constraints and Monitoring

Constraints express behavioral rules that a computation must satisfy. must_match asserts that a pattern must occur; never asserts that a pattern must never occur. Constraints are checked against the causal event graph, not just individual events, enabling rules like "every request must eventually receive a response."

constraints.py python
from pyrapide import must_match, never

# Every reading must trigger an alert
must_match(Pattern.seq("Sensor.reading", "Alerter.alert"), name="alert_follows_reading")

# An alert must never occur without a preceding reading
never(Pattern.match("Alerter.alert").without_cause("Sensor.reading"), name="no_spurious_alerts")

Read the full Constraints documentation →


Clocks and Temporal Ordering

Clocks assign temporal coordinates to events. PyRapide supports both logical clocks (Lamport timestamps that respect causality) and wall clocks (real-time timestamps for human-readable ordering). Logical clocks guarantee that if event A caused event B, then clock(A) < clock(B). This is a property that wall clocks cannot provide in distributed systems.

Read the full Clocks documentation →


Advanced Topics

Beyond the core model, PyRapide provides a rich set of capabilities for real-world systems:

  • Streaming: Process events from multiple concurrent sources in real time with sliding-window semantics.
  • MCP Integration: Translate Model Context Protocol events into causally-linked graphs for multi-server observability.
  • LLM Integration: Trace causal chains through LLM tool calls, prompt-response pairs, and agentic workflows.
  • Analysis: Root-cause analysis, forward/backward slicing, impact sets, and causal path queries.
  • Prediction: Forecast likely future events based on observed causal patterns.
  • Anomaly Detection: Identify deviations from expected causal behavior in real time.
  • Serialization: Save and restore computations in JSON, MessagePack, or custom formats.
  • Visualization: Render causal event graphs as interactive DAG diagrams.
i Note

Each advanced topic includes full API reference and worked examples. Install optional extras like pyrapide[viz] or pyrapide[prediction] to unlock additional capabilities.