Skip to main content

Composable async trigger framework

Project description

triggr

CI PyPI Python Coverage License

Composable async trigger framework for Python.

Provides building blocks for polling loops, parallel task execution, stream-based processing, and long-running service management.

Installation

pip install triggr

Quick start

Implement Source and Worker, wire them into a trigger:

from triggr import PollingTrigger, PollingConfig, Outcome

class PendingOrderSource:
    async def retrieve(self) -> list[Order]:
        return await db.fetch_pending_orders(limit=50)

class FulfillmentWorker:
    async def complete(self, order: Order) -> Outcome:
        if await warehouse.ship(order):
            return Outcome.SUCCESS
        return Outcome.FAILED

    async def is_stale(self, order: Order) -> bool:
        return await db.is_cancelled(order.id)

config = PollingConfig(polling_interval=30.0, parallelism=4)
trigger = PollingTrigger(PendingOrderSource(), FulfillmentWorker(), config)
trigger.run()

Trigger types

Type Use when
PollingTrigger Tasks live in a store; poll on an interval
StreamTrigger Tasks arrive via an AsyncIterator
PeriodicTrigger Run a task on a fixed interval
ScheduledSource Adapt a time-ready lister into a PollingTrigger source

Managing triggers together

TriggerService registers, starts, and monitors a named collection:

from triggr import TriggerService, PollingTrigger, PeriodicTrigger, PollingConfig

config = PollingConfig(polling_interval=30.0, parallelism=4)

svc = TriggerService(expected={"orders", "inventory-sync"})
svc.register("orders", PollingTrigger(PendingOrderSource(), FulfillmentWorker(), config))
svc.register("inventory-sync", PeriodicTrigger(InventorySyncWorker(), interval=60.0))
svc.start_all()

svc.is_healthy()        # True if all triggers are healthy
svc.trigger_health()    # {"orders": True, "inventory-sync": True}
svc.close_all()

When expected is provided, start_all() raises if the registered set doesn't match exactly.

Readiness gates

Gates block work until a condition is met. Pass one to any trigger via ready_gate:

from triggr import EventGate, CompositeGate, PollingTrigger

db_gate = EventGate()
warehouse_gate = EventGate()
gate = CompositeGate(db_gate, warehouse_gate)

trigger = PollingTrigger(source, worker, config, ready_gate=gate)
trigger.run()

# From another coroutine, block until ready:
db_gate.set_not_ready()
await db.reconnect()
db_gate.set_ready()     # trigger resumes only when both gates are ready

Long-running services

RetryingService keeps a ManagedService alive with two-level retry:

from triggr import RetryingService, LONG_RUNNING

async def create_shipment_stream() -> ShipmentStreamService:
    client = await warehouse.connect()
    return ShipmentStreamService(client)

svc = RetryingService(factory=create_shipment_stream, retry_policy=LONG_RUNNING)
svc.run()

Error classification

Implement ErrorClassifier to distinguish transient from fatal errors:

from triggr import ErrorClassifier, ErrorKind

class PaymentGatewayClassifier:
    def classify(self, error: Exception) -> ErrorKind:
        if isinstance(error, GatewayTimeoutError):
            return ErrorKind.TRANSIENT
        return ErrorKind.FATAL

Pass it to any trigger or RetryingService via error_classifier.

API reference

Full module documentation is in the module docstrings. Generated API docs coming soon.

Development

Requires Nix and direnv:

direnv allow   # activates the nix shell
pytest         # runs the full test suite

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

triggr-0.1.0.tar.gz (23.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

triggr-0.1.0-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file triggr-0.1.0.tar.gz.

File metadata

  • Download URL: triggr-0.1.0.tar.gz
  • Upload date:
  • Size: 23.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for triggr-0.1.0.tar.gz
Algorithm Hash digest
SHA256 119e968b38f2362d5f4ce859a762d3ae07549f23d0d8c23d686345aaee314b66
MD5 a0112dab0af84e70c02875a242612ea2
BLAKE2b-256 77f0790ee27825b2b91ef1a9fd9b699ac6707806deb729427b46ad5fd0cff8e1

See more details on using hashes here.

File details

Details for the file triggr-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: triggr-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for triggr-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d00141b832f869d9ab0941334500da7ba16700dfe9675fe9cfe53e56ebf663b7
MD5 e3c34b31e647f2c6018e34341efe40b3
BLAKE2b-256 4e540eca813cca4e53016ae881c66b7f04e19c476e9a09b665766ea7980cbffa

See more details on using hashes here.

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