# Getting started: Pub/Sub in Python
This guide will get you started with Ably Pub/Sub in Python.
You'll establish a realtime connection to Ably and learn to publish and subscribe to messages. You'll also implement presence to track other online clients, and learn how to retrieve message history.
> **Note**
>
> Using an AI coding assistant? [Teach it Ably](https://ably.com/docs/platform/ai-llms.md#agent-skills) with Agent Skills for all popular AI coding agents. Run `claude plugin add ably/agent-skills` or `npx skills add ably/agent-skills` to get started.
## Prerequisites
1. [Sign up](https://ably.com/signup) for an Ably account.
2. Create a [new app](https://ably.com/accounts/any/apps/new), and create your first API key in the **API Keys** tab of the dashboard.
3. Your API key will need the `publish`, `subscribe`, `presence` and `history` capabilities.
4. Install [Python](https://www.python.org/downloads/) version 3.8 or greater.
5. Create a new project and install the Ably Pub/Sub Python SDK:
### Shell
```
# Create a new directory for your project
mkdir ably-python-quickstart
cd ably-python-quickstart
# Create a virtual environment (recommended)
python -m venv venv
source venv/bin/activate # On Windows use: venv\Scripts\activate
# Install the Ably SDK
pip install ably-pubsub-server
```
> **Note**
>
> Upgrading from the `ably` 3.x package? Version 4.0 is published as `ably-pubsub-server`, and changes the imports and how you create a client. See the [upgrade guide](https://github.com/ably/ably-pubsub-python/blob/main/UPDATING.md).
### (Optional) Install Ably CLI
Use the [Ably CLI](https://ably.com/docs/platform/tools/cli.md) as an additional client to quickly test Pub/Sub features. It can simulate other clients by publishing messages, subscribing to channels, and managing presence states.
[`ably init`](https://ably.com/docs/cli/init.md) installs the Ably CLI, authenticates, and sets the default app and API key in a single command:
#### Shell
```
npx @ably/cli init
```
> **Note**
>
> The code examples in this guide include a demo API key. If you wish to interact with the Ably CLI and view outputs within your Ably account, ensure that you replace them with your own API key.
## Step 1: Connect to Ably
Clients establish a connection with Ably when they instantiate an SDK instance. This enables them to send and receive messages in realtime across channels.
Create a `get_started.py` file in your project and add the following function to instantiate the SDK and establish a connection to Ably. At the minimum you need to provide an authentication mechanism. The Python SDK creates server clients, which should authenticate with an API key; see [Server clients and token authentication](https://ably.com/docs/auth/token.md#server-token-auth). A [`client_id`](https://ably.com/docs/auth/identified-clients.md) ensures the client is identified, which is required to use certain features, such as presence:
### Python
```
import asyncio
from ably.pubsub.server import create_realtime_client
async def get_started():
# Initialize the Ably Realtime client
async with create_realtime_client(key="your-api-key", client_id="my-first-client") as pubsub_realtime_client:
def on_state_change(state_change):
if state_change.current.value == "connected":
print("Made my first connection!")
pubsub_realtime_client.connection.on(on_state_change)
await pubsub_realtime_client.connection.once_async("connected")
await asyncio.Event().wait()
asyncio.run(get_started())
```
The Python SDK uses `asyncio` to provide asynchronous operations. This allows the client to handle events such as connection state changes, message receipt, and presence updates without blocking the main thread.
You can monitor the lifecycle of clients' connections by registering a listener that will emit an event every time the connection state changes. For now, run the function with `python get_started.py` to log a message to the console to know that the connection attempt was successful. You'll see the message printed to your console, and you can also inspect the connection event in the dev console of your app.
## Step 2: Subscribe to a channel and publish a message
Messages contain the data that a client is communicating, such as a short 'hello' from a colleague, or a financial update being broadcast to subscribers from a server. Ably uses channels to separate messages into different topics, so that clients only ever receive messages on the channels they are subscribed to.
Add the following lines to your `get_started` function before the `await asyncio.Event().wait()` line to create a channel instance and register a listener to subscribe to the channel. Then run it with `python get_started.py`:
### Python
```
# Get a channel instance
channel = pubsub_realtime_client.channels.get("my-first-channel")
# Subscribe to messages on the channel
def on_message(message):
print(f"Received message: {message.data}")
await channel.subscribe(on_message)
```
Use the Ably CLI to publish a message to your first channel. The message will be received by the client you've subscribed to the channel, and be logged to the console.
### Shell
```
ably channels publish my-first-channel 'Hello!'
```
In a new terminal tab, subscribe to the same channel using the CLI:
### Shell
```
ably channels subscribe my-first-channel
```
Publish another message using the CLI and you will see that, in your other Terminal window, it's received instantly by the client you have running locally, as well as the subscribed terminal instance.
To publish a message with the client running in your IDE, you can add the following line to your `get_started` function before the `await asyncio.Event().wait()` line:
### Python
```
await channel.publish("example", "A message sent from my first client!")
```
## Step 3: Presence
Presence enables clients to be aware of one another if they are present on the same channel. You can then show clients who else is online, provide a custom status update for each, and notify the channel when someone goes offline. With the Python SDK you can both enter the presence set and retrieve it. Your client was created with a `client_id`, so it can announce its own presence on a channel.
Have a client join the presence set using the Ably CLI:
### Shell
```
ably channels presence enter my-first-channel --data '{"status":"learning about Ably!"}'
```
Add the following lines to your `get_started` function before the `await asyncio.Event().wait()` line to retrieve the list of members in the presence set. Then run it with `python get_started.py`:
### Python
```
members = await channel.presence.get()
member_ids = [member.client_id for member in members]
print(f"Members in presence set: {member_ids}")
```
## Step 4: Retrieve message history
You can retrieve previously sent messages using the history feature. Ably stores all messages for 2 minutes by default in the event a client experiences network connectivity issues. You can [extend the storage period](https://ably.com/docs/storage-history/storage.md) of messages if required.
If more than 2 minutes has passed since you published a regular message (excluding the presence events), then you can publish some more before trying out history. You can use the Pub/Sub SDK, Ably CLI or the dev console to do this.
For example, using the Ably CLI to publish 5 messages:
### Shell
```
ably channels publish --count 5 my-first-channel "Message number {{.Count}}"
```
Add the following lines to your `get_started` function before the `await asyncio.Event().wait()` line to retrieve any messages that were recently published to the channel. Then run it with `python get_started.py`:
### Python
```
# Retrieve message history
history = await channel.history()
print([message.data for message in history.items])
```
The output will look similar to the following:
### Json
```
[
'Message number 5',
'Message number 4',
'Message number 3',
'Message number 2',
'Message number 1'
]
```
## Next steps
Continue to explore the documentation with Python as the selected language:
* Understand [token authentication](https://ably.com/docs/auth/token.md) before going to production.
* Understand how to effectively [manage connections](https://ably.com/docs/connect.md#close).
* Explore more [advanced](https://ably.com/docs/pub-sub/advanced.md) Pub/Sub concepts.
You can also explore the [Ably CLI](https://www.npmjs.com/package/@ably/cli) further, or visit the Pub/Sub [API references](https://ably.com/docs/api/realtime-sdk.md).
## Related Topics
- [Overview](https://ably.com/docs/getting-started.md): Getting started with Ably Pub/Sub in your language or framework of choice. Learn how to publish, subscribe, track presence, fetch message history, and manage realtime connections.
- [JavaScript](https://ably.com/docs/getting-started/javascript.md): Get started with Pub/Sub in vanilla JavaScript using Ably. Learn how to publish, subscribe, track presence, fetch message history, and manage realtime connections.
- [Node.js](https://ably.com/docs/getting-started/node.md): Get started with Pub/Sub in JavaScript using Ably. Learn how to publish, subscribe, track presence, fetch message history, and manage realtime connections.
- [Next.js](https://ably.com/docs/getting-started/nextjs.md): Get started with Ably Pub/Sub in Next.js. Learn how to publish and subscribe to messages, track presence, retrieve message history, and manage realtime connections in a Next.js App Router application.
- [React](https://ably.com/docs/getting-started/react.md): A getting started guide for Ably Pub/Sub React that steps through some of the key features using React and Vite.
- [React Native](https://ably.com/docs/getting-started/react-native.md): A getting started guide for Ably Pub/Sub React Native that steps through some of the key features using React Native with Expo.
- [Kotlin](https://ably.com/docs/getting-started/kotlin.md): Get started with Pub/Sub in Kotlin using Ably. Learn how to publish, subscribe, track presence, fetch message history, and manage realtime connections.
- [Swift](https://ably.com/docs/getting-started/swift.md): Get started with Pub/Sub in Swift using Ably. Learn how to publish, subscribe, track presence, fetch message history, and manage realtime connections.
- [Flutter](https://ably.com/docs/getting-started/flutter.md): A getting started guide for Ably Pub/Sub Flutter that steps through some of the key features using Flutter.
- [Java](https://ably.com/docs/getting-started/java.md): A getting started guide for Ably Pub/Sub Java that steps through some of the key features using Java.
- [Go](https://ably.com/docs/getting-started/go.md): Get started with Pub/Sub in Go using Ably. Learn how to publish, subscribe, track presence, fetch message history, and manage realtime connections.
- [Ruby](https://ably.com/docs/getting-started/ruby.md): A getting started guide for Ably Pub/Sub Ruby that steps through some of the key features using Ruby.
- [C# .NET](https://ably.com/docs/getting-started/dotnet.md): A getting started guide for Ably Pub/Sub C# .NET that steps through some of the key features using C# and .NET.
- [Objective C](https://ably.com/docs/getting-started/objective-c.md): A getting started guide for Ably Pub/Sub Objective-C that steps through some of the key features using Objective-C.
- [PHP](https://ably.com/docs/getting-started/php.md): A getting started guide for Ably Pub/Sub PHP that steps through some of the key features using PHP.
- [Laravel](https://ably.com/docs/getting-started/laravel.md): A getting started guide for Ably Pub/Sub Laravel 12 that steps through some of the key features using Laravel.
## Documentation Index
To discover additional Ably documentation:
1. Fetch [llms.txt](https://ably.com/llms.txt) for the canonical list of available pages.
2. Identify relevant URLs from that index.
3. Fetch target pages as needed.
Avoid using assumed or outdated documentation paths.