# Basic Pub/Sub (/sdks/python/tutorials/basic-pubsub)



## Overview [#overview]

This tutorial builds the "hello world" of KubeMQ messaging: a publisher and a subscriber talking over the **Events** pattern. Events are fire-and-forget — the broker fans a message out to every subscriber currently listening on the channel and moves on. There's no persistence, no acknowledgment, and no replay, which makes this the pattern to reach for when you need low-latency, high-throughput broadcast (metrics ticks, live status updates, cache-invalidation signals) and can tolerate losing a message if nobody is listening at the moment it's sent.

You'll wire up `subscribe_to_events` with an `EventsSubscription`, give the subscription a moment to register with the server, then call `publish_event` to publish an `EventMessage`. The subscription's channel accepts every message published to it — every connected subscriber gets its own copy, as opposed to a consumer group where only one member would receive it. &#x2A;*Gotchas:** if the subscriber isn't fully established before you publish, the event is simply gone — there's no queue catching it, which is why the sample sleeps briefly before sending; and because delivery isn't acknowledged, a crashed or disconnected subscriber never knows it missed anything.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Python SDK installed (`pip install kubemq`)

## Code [#code]

```python title="basic_pubsub.py"
"""Example: Basic pub/sub — publish and subscribe to events."""

from __future__ import annotations

import asyncio

from kubemq import (
    AsyncCancellationToken,
    AsyncPubSubClient,
    EventMessage,
    EventReceived,
    EventsSubscription,
    KubeMQConnectionError,
    KubeMQError,
)


async def main() -> None:
    try:
        async with AsyncPubSubClient(
            address="localhost:50000",  # TODO: Replace with your KubeMQ server address
            client_id="python-events-basic-pubsub-client",
        ) as client:
            token = AsyncCancellationToken()

            async def subscriber() -> None:
                async for event in client.subscribe_to_events(
                    subscription=EventsSubscription(
                        channel="python-events.basic-pubsub",
                        on_receive_event_callback=lambda e: None,
                        on_error_callback=lambda e: print(f"Error: {e}"),
                    ),
                    cancellation_token=token,
                ):
                    print(
                        f"Received — Id:{event.id}, Channel:{event.channel}, "
                        f"Body:{event.body.decode('utf-8')}"
                    )

            task = asyncio.create_task(subscriber())
            await asyncio.sleep(1)

            await client.publish_event(
                EventMessage(
                    channel="python-events.basic-pubsub",
                    body=b"hello kubemq",
                )
            )
            print("Event sent")

            await asyncio.sleep(2)
            token.cancel()
            task.cancel()
            try:
                await task
            except asyncio.CancelledError:
                pass
    except KubeMQConnectionError as e:
        print(f"Connection error: {e}")
    except KubeMQError as e:
        print(f"KubeMQ error: {e}")


if __name__ == "__main__":
    asyncio.run(main())

# Expected output:
# Received — Id:<message-id>, Channel:python-events.basic-pubsub, Body:hello kubemq
# Event sent

```

## How It Works [#how-it-works]

* `AsyncPubSubClient` is used as an async context manager (`async with`) so the connection is automatically closed on exit.
* `subscribe_to_events` is an async generator: the `async for` loop yields each `EventReceived` as it arrives from the server.
* `AsyncCancellationToken` signals the generator to stop; calling `token.cancel()` causes the async for loop to finish.
* `publish_event` sends a fire-and-forget `EventMessage`; there is no per-subscriber delivery acknowledgement.

## Related [#related]

* [Pattern overview](/learn/events/getting-started)
* [Python SDK Reference](/sdks/python/reference/events)
* [Cancel Subscription](/sdks/python/how-to/events/cancel-subscription)
* [Consumer Group](/sdks/python/how-to/events/consumer-group)
