Python SDK reference.
cosmonapse Python package - verified against packages/python-sdk. If something here disagrees with the code, the code wins.
Synapse - transport adapters
A Synapse is the message bus. The application picks a backend, passes the adapter to the Dendrite, and never touches the wire format again. All adapters subclass the same abstract Synapse base.
cosmonapse.SynapseThe contract every transport adapter must satisfy. Adapters are responsible for ordering, dedup window, ack semantics, and durability - the SDK assumes at-least-once delivery and in-order per key.
class Synapse(ABC): async def connect(self) -> None: ... async def close(self) -> None: ... async def publish(self, subject: str, signal: Signal) -> None: ... async def subscribe( self, subject: str, handler: Callable[[Signal], Awaitable[None]], *, queue_group: str | None = None, ) -> Subscription: ... async def request( self, subject: str, signal: Signal, *, timeout_s: float = 5.0, ) -> Signal: ...
Bundled adapters
| Class | Process boundary | Use when |
|---|---|---|
| MemorySynapse | single process | Tests, tightly-coupled callers, embedded supervisor processes. |
| DevSynapse | local host, many processes | Client side of cosmo synapse start. TCP + NDJSON; single-host dev only; zero external deps. |
| NatsSynapse | cluster | Production default. Native wildcards and queue groups; low latency. Needs the [nats] extra. |
| KafkaSynapse | cluster | Durable audit log. Trickier request/reply; recommended when retention matters more than latency. |
URL factory
synapse_from_url(url: str) -> SynapseMap a cosmo:// / nats:// / kafka:// URL to a non-connected adapter instance. Raises ValueError for any other scheme. MemorySynapse has no URL - build it directly.
connect_synapse(url: str) -> SynapseSame as synapse_from_url but immediately calls connect().
from cosmonapse import synapse_from_url, connect_synapse, MemorySynapse # Build (does not connect): syn = synapse_from_url("cosmo://localhost:7070") # DevSynapse syn = synapse_from_url("nats://nats:4222") # NatsSynapse syn = synapse_from_url("kafka://broker:9092") # KafkaSynapse # memory:// has no URL - it is process-local, so build it directly: syn = MemorySynapse() # Build + connect in one call: syn = await connect_synapse("cosmo://127.0.0.1:7070")
| URL scheme | Resolves to |
|---|---|
| cosmo://host:port | DevSynapse client (talks to cosmo synapse start) |
| nats://host:port | NatsSynapse |
| kafka://host:port | KafkaSynapse |
| (no URL) | MemorySynapse - construct directly, it is process-local |
Subjects
Subjects follow cosmonapse.<namespace>.<TYPE>. Queue groups load-balance within a group; subscribers with no queue_group form the Doppler population (every matching message goes to each one). Application code must never construct subjects directly - let the Dendrite resolve them.
Have a feature in mind?
The protocol, SDKs, and CLI are still pre-1.0. If something here is missing, ambiguous, or wrong - open an issue and propose a change. Every breaking change is debated in DECISIONS.md first.