# Public API This page documents the stable public API surface of EDRI. Symbols not listed here are internal implementation details and may change without notice in minor releases. ## Stability levels | Level | Meaning | Examples | |-------|---------|----------| | **Stable** | Backward-compatible within the same CalVer version | `edri.EDRI`, `edri.abstract.ManagerBase` | | **Advanced** | Public but requires deeper framework knowledge; may change more often | `edri.api.broker.EventInfo`, `edri.utility.validation` | | **Experimental** | May be removed or redesigned in any release | `edri.abstract.AsyncManagerBase`, `edri.testing` | | **Internal** | Not part of the public API — do not import from outside the framework | `edri.router`, `edri.api.listener` | ## Recommended imports ### Core framework ```python from edri import EDRI from edri.abstract import ManagerBase, ManagerPriorityBase, request, response ``` ### Events and responses ```python from edri.dataclass.event import Event, event from edri.dataclass.response import Response, response as response_decorator ``` ### API events ```python from edri.api.dataclass.api_event import api from edri.api.dataclass import File, Header, Cookie, Scope from edri.config.constant import ApiType ``` ### Workers ```python from edri.abstract.worker import Worker, WorkerThread, WorkerProcess from edri.abstract import ( WorkerController, WorkerNotFoundError, WorkerPolicy, WorkerState, WorkerOutcome, WorkerExit, WorkerStopReason, WorkerTimeout, ) ``` Overriding `__init__` on a `WorkerThread`/`WorkerProcess` subclass needs the module's own `T` TypeVar to keep the generic parameter in the signature: ```python from edri.abstract.worker.worker_thread import T # or .worker_process ``` ### Middleware ```python from edri.api.middleware import Middleware, MiddlewareControl from edri.api.broker import EventInfo ``` `EventInfo` is the `info` parameter type in `Middleware.process_request`/ `process_response`, so any custom middleware needs it. ### Health checking ```python from edri.dataclass.health_checker import HealthReport, Status ``` ### Testing (Experimental) ```python from edri.testing import ManagerTestHarness ``` ### Utility (advanced) ```python from edri.utility.validation import IntegerValidator, StringValidator from edri.utility.transformation import StringTransformer from edri.utility.json_encoder import CustomJSONEncoder from edri.utility.cache import Cache as ManagerCache from edri.utility.function import inject, camel2snake, snake2camel ``` `StringTransformer` and the validators are used the same way, via `inject(...)` on an event field, e.g. `inject(StringTransformer, transform=...)`. ### Built-in events (advanced) EDRI's own Router, Store, Scheduler, and Manager processes communicate through public event types an application can send, subscribe to, or handle — the event class itself is public, but its paired `*Response` dataclass (e.g. `HealthCheckResponse`) is not: read its fields via `event.response`, never import the response class directly. ```python from edri.events.edri.router import HealthCheck, Subscribe, Unsubscribe, LastEvents, SendFrom from edri.events.edri.store import Get, Set, GetCallback, StorePurge, Increment, CompareAndSet, SetIfAbsent, Delete from edri.events.edri.scheduler import Set as SchedulerSet, Update, SetUpdate, Cancel from edri.events.edri.manager import WorkerQuit, WorkerStarted, Restart from edri.events.edri.group import Manager, Router, Scheduler, Store, Switch, Test ``` ### Configuration ```python from edri.config.setting import ENVIRONMENT ``` ### SQLAlchemy integration (experimental) Install `edri[sqlalchemy]`, then import the complete integration from its package root rather than from the implementation submodules: ```python from edri.integrations.sqlalchemy import ( FilterBuilder, ForeignKeyValidator, ORMEvent, ResponseAwareSession, SQLAlchemyManager, SQLAlchemyManagerMixin, SQLAlchemyModelMixin, SQLAlchemyResponseMiddleware, SortBuilder, apply_sorting, orm_count, orm_event, orm_projection, orm_validator, projection, projection_all, projection_one, projection_rows, ) ``` Projection specifications/nodes, strict path helpers, normalization helpers, and their error types are also public through `edri.integrations.sqlalchemy`. See {doc}`/integrations/sqlalchemy` for the complete contract and examples. ## What is NOT public The following are internal and must not be imported by application code: * Each built-in event's paired `*Response` dataclass (e.g. `HealthCheckResponse`, `GetResponse`) — read its fields via `event.response`, never import the class * `edri.router`, `edri.router.connector` — `Router`, `Cache`, `HealthChecker`, `Connector`, and `Socket` are constructed exclusively inside `EDRI()`'s own `start_connector()`/`run()` methods; an application never imports or constructs them directly * `edri.switch.*` (the Switch is a standalone server) * `edri.config.constant`, except `ApiType` * `edri.api.handlers`, `edri.api.listener` (internal API layer); `edri.api.broker`, except `EventInfo` * `edri.utility.function`, except `inject`, `camel2snake`, and `snake2camel` * `edri.utility.queue`, `edri.utility.watcher` * Private attributes (prefixed with `_`) on any public class ## Import paths stability The import paths listed above are part of the compatibility promise. Deeper paths (e.g. `edri.abstract.manager.manager_base.ManagerBase`) may be restructured and should not be relied upon. (version-compatibility)= ## Version compatibility EDRI uses CalVer versioning (``YYYY.MM.DD`` with optional ``rcN`` prerelease suffix). Compatibility requires an **exact version match** across all components in a cluster. Mixed-version deployments are not supported. | Component | Compatibility | |-----------|--------------| | Python package | Exact version match (``from importlib.metadata import version; version('edri')`` must be identical across nodes) | | Switch protocol | Exact version match — the frame header, handshake, pickle schema, and `FrameType` values may change between versions | | Event wire format | Exact version match — event class definitions must be identical on both sides of the wire | | Docker images | Must use the same EDRI CalVer tag as the application package | | Python runtime | Same Python major.minor version recommended; pickle protocol compatibility varies across Python releases | ### What exact-version-match means Every component in a distributed EDRI deployment must run the **same** ``YYYY.MM.DD`` release (including the same ``rcN`` prerelease suffix). This applies to: * The EDRI Python package version on every node. * The Switch Docker image tag (traced back to the same git tag). * Event class definitions, which are serialised with pickle and must match on the sending and receiving side. ### Why not SemVer terms EDRI uses CalVer, not SemVer. Version strings like **{{ VERSION }}** encode a release date, not a semantic version. There is no ``major.minor.patch`` distinction — any release may contain breaking changes. The safety guarantee is: **if every component runs from the exact same release tag, they are compatible.**