Abstract Backend Architecture Overview
Abstract Backend offers a pluggable backend layer that lets applications target stable Python protocols while discovering concrete implementations at runtime. This page explains the major components, how they collaborate, and which supporting systems keep the abstraction reliable.
Section mapβ
- Architecture Overview (this page) β High-level map of the abstraction core, provider plugins, and supporting infrastructure.
- Runtime Flow β Sequence diagrams describing discovery, publish/consume loops, and deployment considerations.
- Provider Lifecycle β Checklist for creating, testing, and distributing new backends.
- Project Structure β Reference for repository layout and supporting assets.
Layered designβ
- Application Integration: Your services import
MessageQueueBackend,AsyncLoopConsumer, and shared type aliases, remaining agnostic to concrete providers. - Abstraction Core: Modules under
abe/backends/message_queue/define the protocols and discovery code that mediate between applications and providers. - Provider Plugins: External packages register entry points that implement the contracts and can be swapped at runtime.
- Supporting Systems: Logging utilities, contract tests, and CI workflows reinforce the guarantees promised by the abstraction.
Core modulesβ
abe/types.pydefines the structural contracts (MessageQueueBackendProtocol,EventHandlerProtocol, JSON aliases) distributed viapy.typed.abe/backends/message_queue/base/exportsMessageQueueBackendandEventConsumerprotocols, capturing publish/consume semantics and consumer lifecycle.abe/backends/message_queue/loader.pydiscovers provider entry points viaimportlib.metadata, applies environment-based selection rules, and falls back toMemoryBackendwhen nothing is installed.abe/backends/message_queue/consumer.pybundles runtime helpers (AsyncLoopConsumer) to execute handlers against any compliant backend.abe/backends/message_queue/service/memory.pyprovides the built-in development backend.
See the API Reference for method-level detail.
Runtime flowβ
The typical request lifecycle:
- Provider selection β
load_backend()inspects theabe.backends.message_queueentry-point group, honoursQUEUE_BACKEND, and instantiates the chosen class throughfrom_env(). - Publishing events β Application code calls
backend.publish(key, payload)usingQueueKey/QueuePayloadaliases to ensure consistent typing. - Consuming events β
AsyncLoopConsumerwrapsbackend.consume(group=...), executing the applicationβs handler coroutine. Cancellation and error handling are standardised here. - Observability β
abe.logging.utilscan standardise log formatting and levels across providers and consumers.
Detailed sequence diagrams live in Runtime Flow.
Provider lifecycleβ
Abstract Backend promotes a clean separation between the core abstraction and provider implementations:
- Implement protocols β Providers subclass nothing; they simply satisfy
MessageQueueBackendProtocoland exposefrom_env(). - Register entry points β
pyproject.tomldeclares the provider underabe.backends.message_queuesoload_backend()can find it. - Package distribution β Providers are published as normal Python packages, allowing teams to install or uninstall them with
pip. - Validation β Tests under
test/contract_test/backends/message_queue/assert new providers honour the contract.
See Provider Lifecycle for an end-to-end checklist.
Supporting infrastructureβ
- Testing: Contract, unit, integration, and e2e suites located under
test/validate both the abstraction and reference implementations. Scripts inscripts/ci/orchestrate type-check and verification runs. - CI/CD: Workflows in
.github/workflows/run tests across multiple Python versions, ensure type distribution (PEP 561), and publish releases. - Documentation: This Docusaurus site (
docs/contents/) anddocs/LOGGING.mddocument runtime features for both consumers and provider authors.
Design principlesβ
- Protocol-first β All core contracts are structural type protocols exported from
abe/types.py, ensuring consumers compile against the same surface. - Runtime pluggability β Providers are discovered via Python entry points; swapping implementations does not require code changes.
- Typed ergonomics β The project distributes
py.typedso editors and CI keep abstractions honest. - Operational clarity β Logging helpers (
abe/logging/utils.py) and contract tests ensure behaviour stays observable and portable.
Related guidesβ
- Structure & Files β Project Structure
- Runtime flow β Runtime Flow
- Provider lifecycle β Provider Lifecycle
- Type system β Type Checking with MyPy