From 25a0d4c7c1f79371ba9b5e62b605a07fb2cda11b Mon Sep 17 00:00:00 2001 From: umair Date: Thu, 3 Sep 2026 14:05:38 +0100 Subject: [PATCH 1/4] docs: rewrite READMEs for the ably-pubsub-server split Root README: PyPI badge and install line move to ably-pubsub-server, a Packages section stating that ably-pubsub-core is internal and the two are versioned in lockstep, three factory-door quickstarts (async realtime, async HTTP, sync HTTP), Python floor raised to 3.8 in the supported-platforms table, and a pointer to the UPDATING migration section. Drops the stale "Full Realtime support unavailable" section: realtime subscribe and presence have shipped. server/README.md and core/README.md are what PyPI renders for the two distributions, so they say what each is for on their own: the server README explains the MAU exemption the -server agent flag buys and the exact factory signatures; the core README says not to depend on it. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 123 +++++++++++++++++++++++++++++++++++++++-------- core/README.md | 27 +++++------ server/README.md | 36 +++++++++++--- 3 files changed, 144 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 4ee29fd5..0e215068 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ![Ably Pub/Sub Python Header](images/pythonSDK-github.png) -[![PyPI version](https://badge.fury.io/py/ably.svg)](https://pypi.org/project/ably/) +[![PyPI version](https://badge.fury.io/py/ably-pubsub-server.svg)](https://pypi.org/project/ably-pubsub-server/) [![License](https://img.shields.io/github/license/ably/ably-python)](https://github.com/ably/ably-python/blob/main/LICENSE) @@ -25,6 +25,28 @@ Everything you need to get started with Ably: --- +## Packages + +Python is a server-side language, so this repository publishes one package for +applications to install, plus the shared implementation it is built on: + +| Distribution | For | Import | +| --- | --- | --- | +| `ably-pubsub-server` | Servers, backends, jobs — any trusted environment holding an API key | `ably_pubsub.server` | +| `ably-pubsub-core` | **Internal.** Ably's own packages only — never depend on it directly | — | + +Installing the package that names the side your code runs on is more than a +naming convention: clients created by `ably-pubsub-server` declare themselves as +server-side on the wire, and server connections are exempt from monthly-active-user +counting. + +Nothing under `ably_pubsub.core` is public API — its module layout and the names +within it may change in any release. Everything supported is re-exported from +`ably_pubsub.server`. The two distributions are versioned and released in +lockstep: `ably-pubsub-server` pins `ably-pubsub-core` to the exact same version. + +--- + ## Supported platforms Ably aims to support a wide range of platforms. If you experience any compatibility issues, open an issue in the repository or contact [Ably support](https://ably.com/support). @@ -33,13 +55,13 @@ The following platforms are supported: | Platform | Support | |----------|--------------------------| -| Python | Python 3.7+ through 3.14 | +| Python | Python 3.8 through 3.14 | > [!NOTE] -> This SDK works across all major operating platforms (Linux, macOS, Windows) as long as Python 3.7+ is available. +> This SDK works across all major operating platforms (Linux, macOS, Windows) as long as Python 3.8 or greater is available. > [!IMPORTANT] -> SDK versions < 2.0.0 are [deprecated](https://ably.com/docs/platform/deprecate/protocol-v1). +> The `ably` package (3.x and earlier) is superseded by `ably-pubsub-server`. See [Migrating from `ably` 3.x](#migrating-from-ably-3x). --- @@ -48,36 +70,100 @@ The following platforms are supported: To get started with your project, install the package: ```sh -pip install ably +pip install ably-pubsub-server ``` > [!NOTE] Install [Python](https://www.python.org/downloads/) version 3.8 or greater. +Optional extras: `crypto` for channel encryption, `vcdiff` for delta decoding, +and `oldcrypto` for the legacy `pycrypto` backend. + +```sh +pip install "ably-pubsub-server[crypto]" +``` + +--- + ## Usage -The following code connects to Ably's realtime messaging service, subscribes to a channel to receive messages, and publishes a test message to that same channel. +Clients are created through the factory functions in `ably_pubsub.server`. They +take exactly the arguments the client constructors take, and return the same +clients. + +### Realtime client + +Connects to Ably's realtime messaging service, subscribes to a channel to +receive messages, and publishes a test message to that same channel. ```python -# Initialize Ably Realtime client -async with AblyRealtime('your-ably-api-key', client_id='me') as realtime_client: - # Wait for connection to be established +import asyncio +from ably_pubsub.server import create_realtime_client + + +async def main(): + realtime_client = create_realtime_client(key='your-ably-api-key', client_id='me') await realtime_client.connection.once_async('connected') print('Connected to Ably') - - # Get a reference to the 'test-channel' channel + channel = realtime_client.channels.get('test-channel') - - # Subscribe to all messages published to this channel + def on_message(message): print(f'Received message: {message.data}') - + await channel.subscribe(on_message) - - # Publish a test message to the channel await channel.publish('test-event', 'hello world') + + await realtime_client.close() + +asyncio.run(main()) +``` + +### HTTP client + +For publishing, history, presence reads, stats and token issuing, with no +persistent connection: + +```python +import asyncio +from ably_pubsub.server import create_http_client + + +async def main(): + async with create_http_client(key='your-ably-api-key') as client: + channel = client.channels.get('test-channel') + await channel.publish('test-event', 'hello world') + +asyncio.run(main()) ``` +### Synchronous HTTP client + +For code that has no event loop. There is no synchronous realtime client. + +```python +from ably_pubsub.server.sync import create_http_client + +client = create_http_client(key='your-ably-api-key') +client.channels.get('test-channel').publish('test-event', 'hello world') +client.close() +``` + +--- + +## Migrating from `ably` 3.x + +Version 4.0.0 moves the SDK to the `ably-pubsub-server` distribution and the +`ably_pubsub.server` import namespace. For most applications the change is +confined to the install line, the import, and the constructor call. +[UPDATING.md](./UPDATING.md) has the full mapping table and worked examples. + +The `ably` package receives security and critical-bug fixes only for one year +from the 4.0.0 release, and is then end-of-life. The two packages can be +installed side by side while you migrate — they use different import packages. + +--- + ## Releases The [CHANGELOG.md](https://github.com/ably/ably-python/blob/main/CHANGELOG.md) contains details of the latest releases for this SDK. You can also view all Ably releases on [changelog.ably.com](https://changelog.ably.com). @@ -93,8 +179,3 @@ Read the [CONTRIBUTING.md](./CONTRIBUTING.md) guidelines to contribute to Ably. ## Support, feedback, and troubleshooting For help or technical support, visit Ably's [support page](https://ably.com/support) or [GitHub Issues](https://github.com/ably/ably-python/issues) for community-reported bugs and discussions. - -### Full Realtime support unavailable - -This SDK currently supports only [Ably REST](https://ably.com/docs/rest) and basic realtime message subscriptions. To access full [Ably Realtime](https://ably.com/docs/realtime) features in Python, consider using the [MQTT adapter](https://ably.com/docs/mqtt). - diff --git a/core/README.md b/core/README.md index 6c3a8697..6b4f15f4 100644 --- a/core/README.md +++ b/core/README.md @@ -2,21 +2,18 @@ **This is an internal implementation package. Do not depend on it directly.** -`ably-pubsub-core` holds the shared implementation of Ably's Pub/Sub SDK for -Python: the HTTP and realtime clients, channels, presence, authentication, -encryption and the message types. It is published so that the packages -applications *do* install can depend on one shared implementation, pinned to an -exact version. - -Install the package that names the side your code runs on instead: - -| Where your code runs | Install | Import | -| --- | --- | --- | -| A server or other trusted environment | `ably-pubsub-server` | `ably_pubsub.server` | - -Nothing under `ably_pubsub.core` is public API. Its module layout, and the -names within it, may change in any release — including patch releases — without -a deprecation cycle. The supported surface is what `ably_pubsub.server` +`ably-pubsub-core` holds the shared implementation of [Ably](https://ably.com)'s +Pub/Sub SDK for Python: the HTTP and realtime clients, channels, presence, +authentication, encryption and the message types. It is published only so that +the packages applications *do* install can share one implementation. + +Install [`ably-pubsub-server`](https://pypi.org/project/ably-pubsub-server/) +instead — it is the public package for servers and other trusted environments, +and it depends on this one at an exact pinned version, released in lockstep. + +Nothing under `ably_pubsub.core` is public API. Its module layout, and the names +within it, may change in any release — including patch releases — without a +deprecation cycle. The supported surface is what `ably_pubsub.server` re-exports. `ably_pubsub` is a [PEP 420](https://peps.python.org/pep-0420/) namespace diff --git a/server/README.md b/server/README.md index a67f195e..07046be2 100644 --- a/server/README.md +++ b/server/README.md @@ -7,9 +7,20 @@ Ably is the platform that powers synchronized digital experiences in realtime. Pub/Sub is its foundational product: publish and subscribe messaging over channels, presence, history, and token issuing. -Choosing the package by side matters beyond naming: connections made by this -package declare themselves as server-side on the wire, and server connections -are exempt from monthly-active-user counting. +## What this package is for + +Install this package when your code runs somewhere you control and trust: a +backend service, an API, a worker or a scheduled job — anywhere that can hold an +API key. It is not for browsers, mobile apps, or anything else shipped to an end +user. + +Choosing the package by side matters beyond naming. Clients created here stamp +`ably-pubsub-server` into the agent identifier they put on the wire — the wire +shape is `ably-pubsub-python/4.0.0 python/3.x ably-pubsub-server` — and that +flag is how the platform classifies the connection as server-side and exempts it +from monthly-active-user counting. + +Requires Python 3.8 or greater. ## Installation @@ -17,8 +28,8 @@ are exempt from monthly-active-user counting. pip install ably-pubsub-server ``` -Optional extras: `crypto` (channel encryption, via pycryptodome) and `vcdiff` -(delta decoding). +Optional extras: `crypto` (channel encryption, via pycryptodome), `vcdiff` +(delta decoding) and `oldcrypto` (the legacy pycrypto backend). ```shell pip install "ably-pubsub-server[crypto]" @@ -58,6 +69,7 @@ from ably_pubsub.server.sync import create_http_client client = create_http_client(key='your-api-key') client.channels.get('some-channel').publish('greeting', 'hello') +client.close() ``` ### Realtime client @@ -82,12 +94,24 @@ asyncio.run(main()) There is no synchronous realtime client. +Both factories take exactly the arguments the underlying client constructors +take: `create_http_client(key=None, token=None, token_details=None, **options)` +and `create_realtime_client(key=None, loop=None, **options)`. + +## Documentation + +- [Ably Pub/Sub docs](https://ably.com/docs/basics) +- [Getting started with Pub/Sub using Python](https://ably.com/docs/getting-started/python) +- [Ably Pub/Sub examples](https://ably.com/examples?product=pubsub) + ## Relationship to other packages - `ably-pubsub-core` — the shared implementation this package is built on. It is an internal package; do not import `ably_pubsub.core` directly. Everything supported is re-exported from `ably_pubsub.server`. -- `ably` — the 3.x package this one replaces. See +- `ably` — the 3.x package this one replaces. It receives security and + critical-bug fixes only for one year from the 4.0.0 release, and is then + end-of-life. The migration is usually three lines: see [UPDATING.md](https://github.com/ably/ably-python/blob/main/UPDATING.md). ## Contributing From 676277af155b156744b7d7d505d75c4a4b269700 Mon Sep 17 00:00:00 2001 From: umair Date: Thu, 3 Sep 2026 14:05:50 +0100 Subject: [PATCH 2/4] docs: add the 3.x to 4.0.0 migration guide New top section in UPDATING.md covering why the split happened (PDR-091b, the MAU classification forcing function, the one-year support window on `ably`), a mapping table that can be applied mechanically, before/after examples for all three doors, and the packaging changes: Python floor, extras, and the fact that `ably` and `ably-pubsub-server` can be installed side by side because the import packages differ. The table is accurate against the branch rather than the plan: every name `ably` exported at top level is re-exported from `ably_pubsub.server`, but Message, PresenceMessage and TokenRequest are reachable only under `ably_pubsub.core`, which the section flags as unsupported with a request to open an issue. Carries the same "naming may change before GA" draft note as ably-ruby's, since 091d is still in review. Co-Authored-By: Claude Opus 5 (1M context) --- UPDATING.md | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/UPDATING.md b/UPDATING.md index 4b4dd719..c5a244a7 100644 --- a/UPDATING.md +++ b/UPDATING.md @@ -1,5 +1,131 @@ # Upgrade / Migration Guide +## Version 3.x (`ably`) to 4.0.0 (`ably-pubsub-server`) + +> **Status: draft.** The public API naming is still under review; the class and +> function names in this section may change before the 4.0.0 GA release. + +Version 4.0.0 splits the SDK into new distributions, following +[PDR-091b](https://ably.atlassian.net/wiki/spaces/product/pages/5362810886). The +`ably` package is superseded: it receives security and critical-bug fixes only +for one year from the 4.0.0 release date, and is then end-of-life. + +### Why + +Under MAU-based pricing the platform must classify every connection as +device-side or server-side. The new packages declare which side they are on +automatically, as part of the agent identifier they put on the wire. The old +`ably` constructors cannot: nothing in them says where the code runs, so once +MAU pricing is live they are rejected on MAU-enabled accounts because the +platform cannot classify them. + +Python is a server-side language, so there is a single new public distribution, +`ably-pubsub-server`, whose factory functions are the only recommended entry +points. It is built on `ably-pubsub-core`, an internal distribution you should +never depend on directly. The objects the factories return are the same clients +as today — channels, presence, history, auth and error handling are unchanged. +For most applications the migration is confined to the install line, the import, +and the constructor call. + +### Mapping + +| 3.x (`ably`) | 4.0 (`ably-pubsub-server`) | +| --- | --- | +| `pip install ably` | `pip install ably-pubsub-server` | +| `pip install ably[crypto]` | `pip install ably-pubsub-server[crypto]` | +| `from ably import AblyRest` | `from ably_pubsub.server import create_http_client` | +| `AblyRest(key=...)` | `create_http_client(key=...)` | +| `from ably import AblyRealtime` | `from ably_pubsub.server import create_realtime_client` | +| `AblyRealtime(key=...)` | `create_realtime_client(key=...)` | +| `from ably.sync import AblyRestSync` | `from ably_pubsub.server.sync import create_http_client` | +| `AblyRestSync(key=...)` | `create_http_client(key=...)` (from `ably_pubsub.server.sync`) | +| `from ably import X` (any name exported by `ably`) | `from ably_pubsub.server import X` | +| `from ably.types.channeloptions import ChannelOptions` | `from ably_pubsub.server import ChannelOptions` | +| `from ably.util.crypto import CipherParams` | `from ably_pubsub.server import CipherParams` | +| `from ably.types.message import Message` | `from ably_pubsub.core.types.message import Message` (see below) | + +Every name that `ably` exported from its top level is re-exported from +`ably_pubsub.server`, along with `TokenDetails`: + +``` +AblyAuthException, AblyException, AblyRealtime, AblyRest, AblyVCDiffDecoder, +Annotation, AnnotationAction, Auth, Capability, ChannelMode, ChannelOptions, +CipherParams, DeviceDetails, IncompatibleClientIdException, MessageAction, +MessageOperation, MessageVersion, Options, PublishResult, Push, +PushChannelSubscription, TokenDetails, UpdateDeleteResult, VCDiffDecoder +``` + +`ably_pubsub.server.sync` re-exports the same set with the synchronous flavours +(`AblyRestSync`, `AuthSync`, `PushSync`; there is no realtime client). + +A few types that 3.x code could reach only by a deep import — `Message`, +`PresenceMessage`, `TokenRequest` and the other submodule-only types — are not +re-exported, and today the equivalent deep import is under `ably_pubsub.core` +(for example `from ably_pubsub.core.types.message import Message`). That works, +but nothing under `ably_pubsub.core` is public API: its layout and names may +change in any release. If you depend on one of these, open an issue so it can be +added to the supported re-export list. + +### Example + +```python +# 3.x +from ably import AblyRest + +client = AblyRest(key='your-api-key') + +# 4.0 +from ably_pubsub.server import create_http_client + +client = create_http_client(key='your-api-key') +``` + +```python +# 3.x +from ably import AblyRealtime + +client = AblyRealtime(key='your-api-key', client_id='me') + +# 4.0 +from ably_pubsub.server import create_realtime_client + +client = create_realtime_client(key='your-api-key', client_id='me') +``` + +```python +# 3.x +from ably.sync import AblyRestSync + +client = AblyRestSync(key='your-api-key') + +# 4.0 +from ably_pubsub.server.sync import create_http_client + +client = create_http_client(key='your-api-key') +``` + +The factories take exactly the keyword arguments the old constructors took: +`create_http_client(key=None, token=None, token_details=None, **options)` and +`create_realtime_client(key=None, loop=None, **options)`, where `**options` is +the same client options as before. The only argument that behaves differently is +`agents`: your entries are preserved, but the package's own `ably-pubsub-server` +entry is always added, so the wire agent reads +`ably-pubsub-python/4.0.0 python/3.x ably-pubsub-server`. + +### Packaging changes + +- **Python floor.** `requires-python` is now `>=3.8` (it was `>=3.7`, though 3.7 + was already untested). Supported versions are 3.8 through 3.14. +- **Extras.** The same extras exist under the new name: + `ably-pubsub-server[crypto]`, `ably-pubsub-server[vcdiff]` and + `ably-pubsub-server[oldcrypto]`. +- **Two distributions.** `ably-pubsub-server` depends on `ably-pubsub-core` + pinned to the exact same version; the two are always released in lockstep. Do + not install or import `ably-pubsub-core` directly. +- **Side-by-side install is safe.** `ably` and `ably-pubsub-server` use + different import packages (`ably` and `ably_pubsub`), so both can be installed + in one environment while you migrate. + ## Version 2.x to 3.0.0 The 3.0.0 version of ably-python introduces several breaking changes to improve the realtime experience and align the API with the Ably specification. These include: From 586a4a42a3e04adb71c009ec8c3e06fafe9646ac Mon Sep 17 00:00:00 2001 From: umair Date: Thu, 3 Sep 2026 14:05:50 +0100 Subject: [PATCH 3/4] docs: add the unreleased 4.0.0 changelog entry Matches the file's existing format (tree link heading, Full Changelog compare link, "Breaking change" section pointing at UPDATING.md), marked "(unreleased)" until the release workflow ships it. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 793f50c0..b6012be6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,45 @@ # Change Log +## [4.0.0](https://github.com/ably/ably-python/tree/v4.0.0) (unreleased) + +[Full Changelog](https://github.com/ably/ably-python/compare/v3.1.2...v4.0.0) + +> This entry describes work in progress on the `integration/v4` branch. Nothing +> is published under these names yet; the heading loses "(unreleased)" when +> 4.0.0 ships. + +### Breaking change + +Version 4.0.0 applies [PDR-091b](https://ably.atlassian.net/wiki/spaces/product/pages/5362810886) +and splits the SDK into new distributions. The `ably` package is superseded: it +receives security and critical-bug fixes only for one year from the 4.0.0 +release date, and is then end-of-life. + +- **New distributions.** `ably-pubsub-server` is the public package for servers + and other trusted environments. It is built on `ably-pubsub-core`, an internal + package that must never be depended on directly; the two are versioned and + released in lockstep, with the server pinning the core to the exact same + version. +- **New import namespace.** `ably` becomes `ably_pubsub.server` (and + `ably.sync` becomes `ably_pubsub.server.sync`). Both installs can coexist in + one environment while migrating, since the import packages differ. +- **Factory doors replace the constructors.** `AblyRest(...)` becomes + `ably_pubsub.server.create_http_client(...)`, `AblyRealtime(...)` becomes + `ably_pubsub.server.create_realtime_client(...)`, and `AblyRestSync(...)` + becomes `ably_pubsub.server.sync.create_http_client(...)`. Each takes exactly + the arguments the constructor it replaces took. +- **Agent identifier.** Clients now report + `ably-pubsub-python/4.0.0 python/ ably-pubsub-server`. The + `ably-pubsub-server` flag is what declares the server side, which is how the + platform exempts these connections from monthly-active-user counting. A new + `agents` client option lets a layered SDK add its own entries. +- **Python floor raised.** `requires-python` is now `>=3.8`; supported versions + are 3.8 through 3.14. +- **`LONG_DESCRIPTION.rst` removed.** Each distribution's PyPI page now renders + its own `README.md`. + +For detailed migration instructions, please refer to the [Upgrading Guide](UPDATING.md). + ## [3.1.2](https://github.com/ably/ably-python/tree/v3.1.2) [Full Changelog](https://github.com/ably/ably-python/compare/v3.1.1...v3.1.2) From e2729b59b32df6459341e227f9721eb805fb34fe Mon Sep 17 00:00:00 2001 From: umair Date: Thu, 3 Sep 2026 14:15:21 +0100 Subject: [PATCH 4/4] docs: map the newly re-exported types in the migration guide #683 added the missing re-exports, so the deep-import caveat is wrong: Message, MessageAnnotations, Presence, PresenceMessage, PresenceAction, TokenRequest, ChannelDetails/Status/Occupancy/Metrics, ChannelState, ChannelStateChange, ConnectionState, ConnectionEvent, ConnectionStateChange, PaginatedResult, HttpPaginatedResponse, Stats, Channel, RealtimeChannel, Connection and RealtimePresence are all on ably_pubsub.server now. Replaced the caveat with a deep-import mapping table, one row per 3.x submodule, and listed the full supported surface verbatim from __all__. Also documents what the sync module omits (realtime and the state types) and the three Sync-suffixed names, plus two names a reader will go looking for and not find in either version: TokenParams is not a class here (token params are plain dicts), and there is no separate ErrorInfo -- AblyException carries code and status_code. Every row was executed as an import against the workspace. Co-Authored-By: Claude Opus 5 (1M context) --- UPDATING.md | 70 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/UPDATING.md b/UPDATING.md index c5a244a7..a89b866b 100644 --- a/UPDATING.md +++ b/UPDATING.md @@ -42,29 +42,61 @@ and the constructor call. | `from ably import X` (any name exported by `ably`) | `from ably_pubsub.server import X` | | `from ably.types.channeloptions import ChannelOptions` | `from ably_pubsub.server import ChannelOptions` | | `from ably.util.crypto import CipherParams` | `from ably_pubsub.server import CipherParams` | -| `from ably.types.message import Message` | `from ably_pubsub.core.types.message import Message` (see below) | -Every name that `ably` exported from its top level is re-exported from -`ably_pubsub.server`, along with `TokenDetails`: +#### Deep imports + +In 3.x many types could only be reached by importing the submodule they were +defined in. In 4.0 all of them are re-exported from `ably_pubsub.server`, so the +submodule path goes away entirely — **the flat import is the supported one**. +Nothing under `ably_pubsub.core` is public API. + +| 3.x deep import | 4.0 | +| --- | --- | +| `from ably.types.message import Message, MessageAnnotations` | `from ably_pubsub.server import Message, MessageAnnotations` | +| `from ably.types.presence import Presence, PresenceMessage, PresenceAction` | `from ably_pubsub.server import Presence, PresenceMessage, PresenceAction` | +| `from ably.types.tokenrequest import TokenRequest` | `from ably_pubsub.server import TokenRequest` | +| `from ably.types.tokendetails import TokenDetails` | `from ably_pubsub.server import TokenDetails` | +| `from ably.types.channeldetails import ChannelDetails, ChannelStatus, ChannelOccupancy, ChannelMetrics` | `from ably_pubsub.server import ChannelDetails, ChannelStatus, ChannelOccupancy, ChannelMetrics` | +| `from ably.types.channelstate import ChannelState, ChannelStateChange` | `from ably_pubsub.server import ChannelState, ChannelStateChange` | +| `from ably.types.connectionstate import ConnectionState, ConnectionEvent, ConnectionStateChange` | `from ably_pubsub.server import ConnectionState, ConnectionEvent, ConnectionStateChange` | +| `from ably.types.stats import Stats` | `from ably_pubsub.server import Stats` | +| `from ably.http.paginatedresult import PaginatedResult, HttpPaginatedResponse` | `from ably_pubsub.server import PaginatedResult, HttpPaginatedResponse` | +| `from ably.rest.channel import Channel` | `from ably_pubsub.server import Channel` | +| `from ably.realtime.channel import RealtimeChannel` | `from ably_pubsub.server import RealtimeChannel` | +| `from ably.realtime.connection import Connection` | `from ably_pubsub.server import Connection` | +| `from ably.realtime.presence import RealtimePresence` | `from ably_pubsub.server import RealtimePresence` | + +The full supported surface of `ably_pubsub.server`: ``` AblyAuthException, AblyException, AblyRealtime, AblyRest, AblyVCDiffDecoder, -Annotation, AnnotationAction, Auth, Capability, ChannelMode, ChannelOptions, -CipherParams, DeviceDetails, IncompatibleClientIdException, MessageAction, -MessageOperation, MessageVersion, Options, PublishResult, Push, -PushChannelSubscription, TokenDetails, UpdateDeleteResult, VCDiffDecoder -``` - -`ably_pubsub.server.sync` re-exports the same set with the synchronous flavours -(`AblyRestSync`, `AuthSync`, `PushSync`; there is no realtime client). - -A few types that 3.x code could reach only by a deep import — `Message`, -`PresenceMessage`, `TokenRequest` and the other submodule-only types — are not -re-exported, and today the equivalent deep import is under `ably_pubsub.core` -(for example `from ably_pubsub.core.types.message import Message`). That works, -but nothing under `ably_pubsub.core` is public API: its layout and names may -change in any release. If you depend on one of these, open an issue so it can be -added to the supported re-export list. +Annotation, AnnotationAction, Auth, Capability, Channel, ChannelDetails, +ChannelMetrics, ChannelMode, ChannelOccupancy, ChannelOptions, ChannelState, +ChannelStateChange, ChannelStatus, CipherParams, Connection, ConnectionEvent, +ConnectionState, ConnectionStateChange, DeviceDetails, HttpPaginatedResponse, +IncompatibleClientIdException, Message, MessageAction, MessageAnnotations, +MessageOperation, MessageVersion, Options, PaginatedResult, Presence, +PresenceAction, PresenceMessage, PublishResult, Push, PushChannelSubscription, +RealtimeChannel, RealtimePresence, SERVER_AGENT_IDENTIFIER, Stats, +TokenDetails, TokenRequest, UpdateDeleteResult, VCDiffDecoder, +create_http_client, create_realtime_client +``` + +`ably_pubsub.server.sync` re-exports the same set minus the realtime types, with +the synchronous flavours under their `Sync` names: `AblyRestSync`, `AuthSync`, +`PushSync`, `ChannelSync`, `PaginatedResultSync` and +`HttpPaginatedResponseSync`. There is no synchronous realtime client, so +`AblyRealtime`, `RealtimeChannel`, `RealtimePresence`, `Connection` and the +channel/connection state types are not there. + +Two names you may go looking for and not find, in either version: + +- **`TokenParams` is not a class in this SDK.** Token params are plain + dictionaries, for example + `await auth.request_token(token_params={'ttl': 3600000, 'client_id': 'me'})`. +- **There is no separate `ErrorInfo` type.** `AblyException` is the equivalent + and carries `code` and `status_code`; it is exported from + `ably_pubsub.server`. ### Example