Skip to content

Release v4.0.0 - #744

Merged
ttypic merged 2 commits into
mainfrom
release/4.0.0
Nov 2, 2026
Merged

ttypic merged 2 commits into
mainfrom
release/4.0.0

Conversation

@ttypic

@ttypic ttypic commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

The 4.0.0 release makes it clear that this is the SDK for code running on a server. It is now published as ably-pubsub-server and imported from ably.pubsub.server, a single module that is the whole public API. The package name is also what coding assistants see in the install step and the import line, so they get the choice right too.

4.0.0 adds LiveObjects, and batch publish and batch presence on the HTTP client. It also removes the APIs and client options deprecated in 3.x, and makes the client behave as the Ably specification and the other Ably SDKs do where 3.x departed from them.

Below is an overview of the major changes in this release.

Please refer to the migration guide for the full details, including a list of all breaking changes and instructions on how to address them.

New package and imports

This repository no longer publishes ably. Install ably-pubsub-server, which installs into the ably.pubsub namespace:

  • Import everything from ably.pubsub.server, or from ably.pubsub.server.sync for the synchronous HTTP client. The packages beneath them, such as ably.pubsub.types, are internal and free to move.
  • ably.pubsub.server now exports every type a client returns, hands to a listener or accepts, including those 3.x left in submodules, such as ConnectionState and PresenceMessage, and the encryption helpers generate_random_key and get_default_params.

Client API naming

  • Clients are created through factory functions instead of constructors: create_realtime_client and create_http_client. Constructing AblyRealtime or AblyRest directly raises TypeError, and the API key is passed as key=, no longer positionally.
  • Annotate clients with the prototypes the factories return: PubSubRealtimeClient and PubSubHttpClient.
  • Rest is renamed Http across the public API, for example RestAnnotations is now HttpAnnotations.
  • The synchronous client's presence, annotations and push admin classes end in Sync, as its other classes already did.

New features

  • LiveObjects on the realtime client, through channel.object, with the path-based API: PathObject, Instance, typed views, subscriptions and batched writes.
  • batch_publish and batch_presence on the HTTP client.
  • The echo_messages client option.
  • The max_message_size client option. HTTP publishes are now checked against it too.
  • The library uses Ably protocol version 6.

Client options

  • The timing options take seconds and end in _seconds, for example disconnected_retry_timeout_seconds and http_request_timeout_seconds. The realtime timing options and fallback_retry_timeout used to take milliseconds. Passing an old name raises a TypeError that names its replacement and converts the value, and every timing option is validated when the client is created.
  • http_max_retry_count counts fallback hosts only, so the default of 3 tries one more host than before.
  • http_request_timeout_seconds also bounds writing a request and waiting for a pooled connection.
  • The HTTP options on client.options read back their defaults rather than None.

Auth and tokens

  • A key no longer overrides an auth_callback, auth_url, token or token_details given alongside it. The client uses token auth and keeps the key for renewal. Pass use_token_auth=False to keep basic auth.
  • Token params reach an auth_url under their wire names, for example clientId rather than client_id, so update your auth server before or together with the clients.
  • TokenDetails.capability is the JSON string the Ably service returned. A TokenDetails known only by its token string has expires, issued and capability set to None.
  • create_token_request() applies default_token_params, and token params given to it or to request_token() replace the defaults rather than merging with them.
  • A realtime client reports its configured client_id before it connects. authorize() keeps an explicit client_id, and a token_details whose client ID conflicts with client_id is rejected when the client is created.

Errors

  • Network errors and timeouts are raised as AblyException, with the httpx exception as its cause: code 50003 for a timeout and 80000 for other network errors.
  • An AblyException raised by an auth_callback reaches the caller unchanged. A callback error with status 403 fails a realtime connection instead of retrying.
  • Invalid arguments to the factories and to push.admin.publish raise AblyException.
  • Seven errors that had their code and status_code the wrong way round now carry them correctly.

Channels

  • channels.release() raises an AblyException with code 90011 unless the channel is INITIALIZED, DETACHED or FAILED. Detach the channel before releasing it.
  • attach() and subscribe() raise when the channel does not reach ATTACHED.
  • Setting channel options replaces them whole, so options without a cipher turn encryption off. channel.options is a ChannelOptions, and HTTP channels accept ChannelOptions too.
  • Channels are no longer attributes of the channels collection: client.channels.my_channel raises AttributeError. Use channels.get(name).
  • A space in a channel name is sent as %20 over HTTP, so it reaches the channel it names rather than one with + in its place.
  • connection.ping() waits for a disconnected connection to reconnect instead of raising.

Values and types

  • PresenceMessage.timestamp is milliseconds since the epoch, as Message.timestamp is, rather than a datetime.
  • Stats.interval_time is a timezone-aware datetime.
  • PresenceAction is an IntEnum.
  • HttpPaginatedResponse.error_code is an int, and HttpPaginatedResponse.headers a read-only, case-insensitive mapping.
  • Push removals return None, PaginatedResult no longer has a response attribute, and DeviceDetails.push is a DevicePushDetails.
  • A timedelta token ttl is sent exact to the millisecond.

Removed APIs

  • The environment, rest_host and realtime_host client options are removed in favour of endpoint, and auth_token in favour of token. Passing any of them raises TypeError.
  • The log_level option is removed. Configure the ably.pubsub logger instead.
  • The recover option is removed, since connection recovery was never implemented.
  • The unused timeout argument is removed from request methods, and paginated from stats().

Supported platforms changes

  • Support for Python 3.7 has been dropped.

Summary by CodeRabbit

  • Release

    • Updated the package to version 4.0.0.
  • Compatibility

    • The release notes document changes to package imports, client API naming, options, authentication, error handling, channels, and values.
    • Some APIs have been removed, and Python 3.7 is no longer supported.
  • Bug Fixes

    • The release notes include bug fixes for this version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 55 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 262be428-a4d0-488f-b3df-d51316e21fc9
Commits

Reviewing files that changed from the base of the PR and between 74c3011 and b2497eb.

Files ignored due to path filters: 1
  • uv.lock is excluded by !**/*.lock
Files selected for processing: 3
  • CHANGELOG.md
  • ably/pubsub/version.py
  • pyproject.toml

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 09627e0f-57c5-40d7-bb44-d2ea1d31f37a
Commits

Reviewing files that changed from the base of the PR and between 55a891e and 74c3011.

Files ignored due to path filters: 1
  • uv.lock is excluded by !**/*.lock
Files selected for processing: 3
  • CHANGELOG.md
  • ably/pubsub/version.py
  • pyproject.toml

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

This PR adds the 4.0.0 changelog entry and updates the project and library version values from 3.1.4 to 4.0.0. The changelog describes package and API changes, new features, behavior updates, removals, fixes, and the end of Python 3.7 support.

Changes

4.0.0 Release

Layer / File(s) Summary
Release notes and version values
CHANGELOG.md, ably/pubsub/version.py, pyproject.toml
The changelog records the 4.0.0 release changes. The project and library version values change from 3.1.4 to 4.0.0.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Other

Possibly related PRs

Suggested reviewers: owenpearson

Merge Risk: Minimal · previous review 74c30

The release notes and version updates present no identified merge-blocking risk. Merge after normal release checks pass.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the 4.0.0 release, which matches the version updates and changelog entry.
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 1 files. (2 skipped: 2 unsupported.)

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

I’m a rabbit with release notes bright,
Four point oh is penned tonight,
Version tags now match the page,
New notes mark each release stage,
I thump my paws and hop away!

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@owenpearson owenpearson left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :shipit:

@ttypic
ttypic merged commit c000585 into main Nov 2, 2026
15 of 16 checks passed
@ttypic
ttypic deleted the release/4.0.0 branch November 2, 2026 13:00

This branch was successfully deployed

2 active deployments
staging/pull/744/features — b2497eb0 Deployed Nov 2, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants