Modules#
An overview of the packages that make up litestar_events.
The API reference below is generated automatically from the source docstrings.
Package (litestar_events)#
Shared emitter machinery, configuration, and the Litestar plugin.
Top-level package for the project.
Configuration shared by the producer and the worker process.
- class litestar_events.config.EventsConfig(backend=None, backend_options=<factory>, role=None, codec=None, typed_decoding=True, local_listeners=(), request_id_header=None, request_id_exclude_path_pattern=None, echo_request_id=True, drain_timeout=30.0)[source]#
Bases:
objectSettings for
EventsPlugin.Import the same config in the web app and the worker: the worker loads the same Litestar app (
litestar events run) and only the role differs.- Parameters:
backend (type[BaseEventEmitterBackend] | None)
role (EventsRole | str | None)
codec (Codec | None)
typed_decoding (bool)
local_listeners (Sequence[EventListener])
request_id_header (str | None)
request_id_exclude_path_pattern (str | tuple[str, ...] | None)
echo_request_id (bool)
drain_timeout (float)
- backend: type[BaseEventEmitterBackend] | None = None#
Emitter backend to install on the app.
Nonekeeps the app’s own.
- role: EventsRole | str | None = None#
Role for this process;
events runalways usesworker.
- typed_decoding: bool = True#
Convert worker-side arguments to the listener’s annotated types.
Only applies to the default codec; a custom
codecdecides for itself.
- local_listeners: Sequence[EventListener] = ()#
Listeners that run in the web (producer) process instead of the worker.
A
producercalls them directly fromapp.emit()without the broker; aworkerskips them. Each must also be in the app’slisteners.
- request_id_header: str | None = None#
Request header whose value becomes the correlation id of events emitted while serving the request (e.g.
"x-request-id").Noneadds no middleware.
- class litestar_events.config.EventsRole(*values)[source]#
-
What an emitter does in the current process.
- EMBEDDED = 'embedded'#
Publish and consume in the same process (the historical behavior).
- PRODUCER = 'producer'#
no broker subscription, no consumer task.
- Type:
Publish only
- WORKER = 'worker'#
listeners run here,
emitis rejected.- Type:
Consume only
- litestar_events.config.resolve_role(role=None)[source]#
Resolve
roleto anEventsRole;Nonemeans embedded.- Raises:
ValueError – if
roleis not a valid role.- Parameters:
role (EventsRole | str | None)
- Return type:
Litestar plugin wiring the emitter backend and the events CLI group.
- class litestar_events.plugin.EventsPlugin(config=None)[source]#
Bases:
InitPluginProtocol,CLIPluginInstall an emitter backend and add the
litestar eventscommands.Use the same plugin and config in the web app and the worker. The worker runs the same Litestar app through
litestar events run, which always consumes only; setEventsConfig(role="producer")so the web process publishes only.Plugin order matters for the request id: with
request_id_headerset, the middleware goes first in the app’s list when this plugin initializes, so listEventsPluginlast inplugins=[...]to keep it outermost.- Parameters:
config (EventsConfig | None)
- on_app_init(app_config)[source]#
Receive the
AppConfiginstance after on_app_init hooks have been called.Examples
from litestar import Litestar, get from litestar.di import Provide from litestar.plugins import InitPluginProtocol def get_name() -> str: return "world" @get("/my-path") def my_route_handler(name: str) -> dict[str, str]: return {"hello": name} class MyPlugin(InitPluginProtocol): def on_app_init(self, app_config: AppConfig) -> AppConfig: app_config.dependencies["name"] = Provide(get_name) app_config.route_handlers.append(my_route_handler) return app_config app = Litestar(plugins=[MyPlugin()])
- Parameters:
app_config¶ – The
AppConfiginstance.app_config (AppConfig)
- Returns:
The app config object.
- Return type:
AppConfig
- on_cli_init(cli)[source]#
Called when the CLI is initialized.
This can be used to extend or override existing commands.
- Parameters:
cli¶ – The root
click.Groupof the Litestar CLIcli (Group)
- Return type:
None
Examples
from litestar import Litestar from litestar.plugins import CLIPluginProtocol from click import Group class CLIPlugin(CLIPluginProtocol): def on_cli_init(self, cli: Group) -> None: @cli.command() def is_debug_mode(app: Litestar): print(app.debug) app = Litestar(plugins=[CLIPlugin()])
Wire format and listener-argument binding shared by every backend.
The producer and the worker must agree on the bytes that travel through the
broker. This module is that single definition: JSONCodec encodes
emit(event_id, *args, **kwargs) into a versioned JSON envelope and decodes
it again on the worker, optionally converting the decoded values into the
types annotated on the listener’s parameters.
- litestar_events.codec.WIRE_VERSION = 1#
Version stamped on every message (
"v"). Messages without it are version 1 messages written before the field existed. The envelope fields added since ("cid","h") are optional, so the version is unchanged.
- class litestar_events.codec.Codec(*args, **kwargs)[source]#
Bases:
ProtocolHow events cross the broker and reach listeners.
- class litestar_events.codec.JSONCodec(*, typed=True, type_encoders=None, type_decoders=None)[source]#
Bases:
objectJSON envelope:
v,cid,h,argsandkwargskeys.Encoding uses Litestar’s serializer, so
datetime,UUID,Decimal, dataclasses and msgspec/Pydantic models are all supported on the producer.- Parameters:
typed¶ – when
True(default), the worker converts each decoded argument to the type annotated on the listener’s parameter (order: Order,when: datetime) before calling it. Unannotated parameters, and listeners whose annotations cannot be resolved, get plain JSON values. WhenFalse, every listener gets plain JSON values, as in earlier releases.type_encoders¶ – extra Litestar-style type encoders for
encode.type_decoders¶ – extra
(predicate, decoder)pairs for typed decoding.typed (bool)
type_encoders (dict[Any, Callable[[Any], Any]] | None)
type_decoders (Sequence[tuple[Callable[[Any], bool], Callable[[Any, Any], Any]]] | None)
A listener whose single parameter is a model (dataclass, msgspec
Struct, Pydantic model orTypedDict) can receive the whole keyword payload:app.emit("order_created", id=1, total=9)populatesorder: Order. A parameter annotatedEventContextis injected with the event’s id, headers and correlation id.- content_type = 'application/json'#
Advertised on brokers with a native content-type field (RabbitMQ).
- class litestar_events.codec.Message(args=(), kwargs=<factory>, headers=<factory>, correlation_id=None)[source]#
Bases:
objectOne event as it crosses the broker.
- litestar_events.codec.listener_name(fn)[source]#
Name of the user’s function behind a listener’s
fn, for messages.- Parameters:
fn (Callable[..., Any])
- Return type:
Event headers, correlation ids and the listener-side event context.
Every event carries a correlation id and optional string headers across the
broker. Set them for the events emitted in a block with event_headers();
read them in a listener by annotating a parameter as EventContext or by
calling current_event(). Events emitted from inside a listener inherit its
correlation id, so one request can be traced across processes.
- class litestar_events.context.EventContext(event_id, headers, correlation_id)[source]#
Bases:
objectWhat a listener can know about the event it is handling.
Annotate a listener parameter with this type and it is injected:
@listener("order_created") async def on_order(order_id: int, ctx: EventContext) -> None: ...
- litestar_events.context.current_event()[source]#
Return the event the running listener is handling, else
None.- Return type:
EventContext | None
- litestar_events.context.event_headers(headers=None, /, *, correlation_id=None, **extra)[source]#
Attach headers (and optionally a correlation id) to events emitted inside.
Nested blocks merge, inner values winning. Header names and values are strings. Example:
with event_headers(tenant="acme", correlation_id=request_id): app.emit("order_created", order_id=1)
- litestar_events.context.outgoing_correlation_id()[source]#
Correlation id for an event emitted now.
The explicit one from
event_headers(), else the one of the event the current listener handles, else a new id.- Return type:
- litestar_events.context.use_event(context)[source]#
Make
contextthe current event; used while a listener runs.- Parameters:
context (EventContext)
- Return type:
Generator[None, None, None]
ASGI middleware tying a request id to the events emitted while serving it.
- class litestar_events.middleware.RequestIdMiddleware(*, header='x-request-id', echo=True, exclude_path_pattern=None)[source]#
Bases:
ASGIMiddlewareUse the request’s id as the correlation id of events emitted during it.
The id is read from
header(x-request-idby default). A missing or unsafe value is replaced with a generated one. Events emitted while the request is handled carry the id, so a worker’s logs can be tied back to the request. Withechothe id is also set on the response.Routes can opt out with
opt={"exclude_request_id": True}or by path throughexclude_path_pattern.Add it through
EventsConfig(request_id_header=...), or register it yourself as ordinary Litestar middleware.
Backends (litestar_events.contrib)#
Drop-in BaseEventEmitterBackend implementations, one subpackage per
transport. See each backend’s docstring for its delivery semantics and
constructor arguments.