From d23c98c68536d6568dbdede4193120a0b0ff66fa Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Fri, 16 Oct 2026 13:08:40 +0530 Subject: [PATCH] pubsub: export the encryption helpers from ably.pubsub.server 4.0 makes ably.pubsub.server the whole public API, but its export list was carried over from 3.x's top-level ably package, which only re-exported CipherParams. 3.x users reached generate_random_key and get_default_params through ably.util.crypto, a submodule that 4.0 moves and declares internal, so 4.0 left no public way to generate a key (RSE2) or build default cipher params. Export both from ably.pubsub.server and ably.pubsub.server.sync, show the 3.x to 4.0 import in UPDATING.md, and make the missing-crypto error name the ably-pubsub-server[crypto] extra instead of the old ably[crypto]. --- UPDATING.md | 12 ++++++++++++ ably/pubsub/server/__init__.py | 4 +++- ably/pubsub/server/sync.py | 4 +++- ably/pubsub/util/nocrypto.py | 2 +- test/unit/pubsub_server_test.py | 6 ++++++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/UPDATING.md b/UPDATING.md index a2aa7db7..a63e8ea1 100644 --- a/UPDATING.md +++ b/UPDATING.md @@ -49,6 +49,18 @@ Where 3.x left you reaching into submodules such as `ably.types.message` or the whole public API, and `ably.pubsub.server.sync` is its synchronous counterpart. The packages beneath them are internal and free to move. +For example, the encryption helpers move from `ably.util.crypto`: + +Example 3.x code: +```python +from ably.util.crypto import generate_random_key, get_default_params +``` + +Example 4.0.0 code: +```python +from ably.pubsub.server import generate_random_key, get_default_params +``` + ### Clients are built by factories `AblyRest` and `AblyRealtime` are internal in 4.0.0 and raise `TypeError` if diff --git a/ably/pubsub/server/__init__.py b/ably/pubsub/server/__init__.py index 41efc61e..a95546c5 100644 --- a/ably/pubsub/server/__init__.py +++ b/ably/pubsub/server/__init__.py @@ -38,7 +38,7 @@ from ably.pubsub.types.options import Options, VCDiffDecoder from ably.pubsub.types.tokendetails import TokenDetails from ably.pubsub.util.construction import factory_construction -from ably.pubsub.util.crypto import CipherParams +from ably.pubsub.util.crypto import CipherParams, generate_random_key, get_default_params from ably.pubsub.util.exceptions import AblyAuthException, AblyException, IncompatibleClientIdException from ably.pubsub.vcdiff.defaultvcdiffdecoder import AblyVCDiffDecoder from ably.pubsub.version import api_version, lib_version @@ -275,5 +275,7 @@ def create_realtime_client(**kwargs) -> PubSubRealtimeClient: 'api_version', 'create_http_client', 'create_realtime_client', + 'generate_random_key', + 'get_default_params', 'lib_version', ] diff --git a/ably/pubsub/server/sync.py b/ably/pubsub/server/sync.py index 5ccab431..edcf8fb9 100644 --- a/ably/pubsub/server/sync.py +++ b/ably/pubsub/server/sync.py @@ -24,7 +24,7 @@ from ably.pubsub.sync.types.options import Options, VCDiffDecoder from ably.pubsub.sync.types.tokendetails import TokenDetails from ably.pubsub.sync.util.construction import factory_construction -from ably.pubsub.sync.util.crypto import CipherParams +from ably.pubsub.sync.util.crypto import CipherParams, generate_random_key, get_default_params from ably.pubsub.sync.util.exceptions import AblyAuthException, AblyException, IncompatibleClientIdException from ably.pubsub.sync.vcdiff.defaultvcdiffdecoder import AblyVCDiffDecoder from ably.pubsub.version import api_version, lib_version @@ -84,5 +84,7 @@ def create_http_client(**kwargs) -> PubSubHttpClient: 'VCDiffDecoder', 'api_version', 'create_http_client', + 'generate_random_key', + 'get_default_params', 'lib_version', ] diff --git a/ably/pubsub/util/nocrypto.py b/ably/pubsub/util/nocrypto.py index a66669b3..b6b71265 100644 --- a/ably/pubsub/util/nocrypto.py +++ b/ably/pubsub/util/nocrypto.py @@ -2,7 +2,7 @@ class InstallPycrypto: def __getattr__(self, name): raise ImportError( - "This requires to install ably with crypto support: pip install 'ably[crypto]'" + "This requires ably-pubsub-server with crypto support: pip install 'ably-pubsub-server[crypto]'" ) diff --git a/test/unit/pubsub_server_test.py b/test/unit/pubsub_server_test.py index a06d2582..a806f56e 100644 --- a/test/unit/pubsub_server_test.py +++ b/test/unit/pubsub_server_test.py @@ -161,3 +161,9 @@ class TestPublicTypes: def test_message_is_exported(self): assert 'Message' in server.__all__ assert 'Message' in server_sync.__all__ + + # RSE2: channel encryption needs a public way to generate a key and build cipher params + @pytest.mark.parametrize('name', ['generate_random_key', 'get_default_params']) + def test_crypto_helpers_are_exported(self, name): + assert name in server.__all__ + assert name in server_sync.__all__