F
Fabra

Events & Workers

Fabra supports an event-driven path for keeping triggered features up to date:

  1. Your app sends an event to Fabra over HTTP.
  2. Fabra writes the event to Redis Streams.
  3. A Fabra worker process consumes the stream and computes triggered features.
  4. Results are written to the online store (Redis), so GET /features/... is fast.

This is intentionally simple. There’s no “proxy SDK” requirement.

Ingest an event (HTTP)

curl -fsS -X POST "http://127.0.0.1:8000/v1/ingest/purchase?entity_id=u1" \
  -H "Content-Type: application/json" \
  -d '{"amount": 42, "currency": "USD"}'

Redis Streams used

Fabra publishes each event to:

  • fabra:events: (example: fabra:events:purchase)
  • fabra:events:all (shared stream for simpler worker setups)

Run the worker

Load the same feature file you use for fabra serve:

fabra worker features.py

By default, the worker will discover triggers from your registered features and listen on the corresponding streams.

Listen to explicit event types

fabra worker features.py --event-type purchase,refund

Listen to explicit streams (advanced)

fabra worker features.py --streams fabra:events:purchase,fabra:events:refund

Listen to all events

fabra worker features.py --listen-all

Triggered feature functions

Triggered features can optionally accept payload or event:

from fabra.core import FeatureStore

store = FeatureStore()

def purchase_total(user_id: str, payload: dict) -> int:
    return int(payload["amount"])

store.register_feature(
    name="purchase_total",
    entity_name="user",
    func=purchase_total,
    trigger="purchase",
)