From 68b8a801bda42fa92c3478150189bc23fee31873 Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 21 Jan 2026 18:56:45 +0000 Subject: [PATCH 1/2] chore: rename realtime_channel.py and default_vcdiff_decoder.py Renamed files for consistency across SDK --- ably/__init__.py | 2 +- ably/realtime/realtime.py | 2 +- ably/realtime/{realtime_channel.py => realtimechannel.py} | 0 ably/realtime/realtimepresence.py | 2 +- .../{default_vcdiff_decoder.py => defaultvcdiffdecoder.py} | 0 test/ably/realtime/realtimechannel_publish_test.py | 2 +- test/ably/realtime/realtimechannel_test.py | 2 +- test/ably/realtime/realtimechannel_vcdiff_test.py | 2 +- test/ably/realtime/realtimeresume_test.py | 2 +- 9 files changed, 7 insertions(+), 7 deletions(-) rename ably/realtime/{realtime_channel.py => realtimechannel.py} (100%) rename ably/vcdiff/{default_vcdiff_decoder.py => defaultvcdiffdecoder.py} (100%) diff --git a/ably/__init__.py b/ably/__init__.py index ce1a6d0f..2280daa0 100644 --- a/ably/__init__.py +++ b/ably/__init__.py @@ -12,7 +12,7 @@ from ably.types.options import Options, VCDiffDecoder from ably.util.crypto import CipherParams from ably.util.exceptions import AblyAuthException, AblyException, IncompatibleClientIdException -from ably.vcdiff.default_vcdiff_decoder import AblyVCDiffDecoder +from ably.vcdiff.defaultvcdiffdecoder import AblyVCDiffDecoder logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) diff --git a/ably/realtime/realtime.py b/ably/realtime/realtime.py index 9b9c4016..8e980cd0 100644 --- a/ably/realtime/realtime.py +++ b/ably/realtime/realtime.py @@ -3,7 +3,7 @@ from typing import Optional from ably.realtime.connection import Connection, ConnectionState -from ably.realtime.realtime_channel import Channels +from ably.realtime.realtimechannel import Channels from ably.rest.rest import AblyRest log = logging.getLogger(__name__) diff --git a/ably/realtime/realtime_channel.py b/ably/realtime/realtimechannel.py similarity index 100% rename from ably/realtime/realtime_channel.py rename to ably/realtime/realtimechannel.py diff --git a/ably/realtime/realtimepresence.py b/ably/realtime/realtimepresence.py index f3351114..a7dea6e7 100644 --- a/ably/realtime/realtimepresence.py +++ b/ably/realtime/realtimepresence.py @@ -20,7 +20,7 @@ from ably.util.exceptions import AblyException if TYPE_CHECKING: - from ably.realtime.realtime_channel import RealtimeChannel + from ably.realtime.realtimechannel import RealtimeChannel log = logging.getLogger(__name__) diff --git a/ably/vcdiff/default_vcdiff_decoder.py b/ably/vcdiff/defaultvcdiffdecoder.py similarity index 100% rename from ably/vcdiff/default_vcdiff_decoder.py rename to ably/vcdiff/defaultvcdiffdecoder.py diff --git a/test/ably/realtime/realtimechannel_publish_test.py b/test/ably/realtime/realtimechannel_publish_test.py index 1f4a6981..47edd9fa 100644 --- a/test/ably/realtime/realtimechannel_publish_test.py +++ b/test/ably/realtime/realtimechannel_publish_test.py @@ -3,7 +3,7 @@ import pytest from ably.realtime.connection import ConnectionState -from ably.realtime.realtime_channel import ChannelOptions, ChannelState +from ably.realtime.realtimechannel import ChannelOptions, ChannelState from ably.transport.websockettransport import ProtocolMessageAction from ably.types.message import Message from ably.util.crypto import CipherParams diff --git a/test/ably/realtime/realtimechannel_test.py b/test/ably/realtime/realtimechannel_test.py index f12fbea1..c5915c64 100644 --- a/test/ably/realtime/realtimechannel_test.py +++ b/test/ably/realtime/realtimechannel_test.py @@ -3,7 +3,7 @@ import pytest from ably.realtime.connection import ConnectionState -from ably.realtime.realtime_channel import ChannelOptions, ChannelState, RealtimeChannel +from ably.realtime.realtimechannel import ChannelOptions, ChannelState, RealtimeChannel from ably.transport.websockettransport import ProtocolMessageAction from ably.types.message import Message from ably.util.exceptions import AblyException diff --git a/test/ably/realtime/realtimechannel_vcdiff_test.py b/test/ably/realtime/realtimechannel_vcdiff_test.py index af778089..8175bf06 100644 --- a/test/ably/realtime/realtimechannel_vcdiff_test.py +++ b/test/ably/realtime/realtimechannel_vcdiff_test.py @@ -5,7 +5,7 @@ from ably import AblyVCDiffDecoder from ably.realtime.connection import ConnectionState -from ably.realtime.realtime_channel import ChannelOptions +from ably.realtime.realtimechannel import ChannelOptions from ably.types.options import VCDiffDecoder from test.ably.testapp import TestApp from test.ably.utils import BaseAsyncTestCase, WaitableEvent diff --git a/test/ably/realtime/realtimeresume_test.py b/test/ably/realtime/realtimeresume_test.py index 8aae598f..fd03c965 100644 --- a/test/ably/realtime/realtimeresume_test.py +++ b/test/ably/realtime/realtimeresume_test.py @@ -3,7 +3,7 @@ import pytest from ably.realtime.connection import ConnectionState -from ably.realtime.realtime_channel import ChannelState +from ably.realtime.realtimechannel import ChannelState from ably.transport.websockettransport import ProtocolMessageAction from test.ably.testapp import TestApp from test.ably.utils import BaseAsyncTestCase, random_string From c1f170ed57727f263ddf761c1af36f8563827ab1 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 22 Jan 2026 11:00:12 +0000 Subject: [PATCH 2/2] chore: drop relatime prefix for realtime channel and presence also moved channeloptions to types --- .../{realtimechannel.py => channel.py} | 70 +------------------ .../{realtimepresence.py => presence.py} | 2 +- ably/realtime/realtime.py | 2 +- ably/types/channeloptions.py | 70 +++++++++++++++++++ .../realtime/realtimechannel_publish_test.py | 3 +- test/ably/realtime/realtimechannel_test.py | 3 +- .../realtime/realtimechannel_vcdiff_test.py | 2 +- test/ably/realtime/realtimeresume_test.py | 2 +- 8 files changed, 81 insertions(+), 73 deletions(-) rename ably/realtime/{realtimechannel.py => channel.py} (94%) rename ably/realtime/{realtimepresence.py => presence.py} (99%) create mode 100644 ably/types/channeloptions.py diff --git a/ably/realtime/realtimechannel.py b/ably/realtime/channel.py similarity index 94% rename from ably/realtime/realtimechannel.py rename to ably/realtime/channel.py index 792c6717..e0fd6251 100644 --- a/ably/realtime/realtimechannel.py +++ b/ably/realtime/channel.py @@ -2,12 +2,13 @@ import asyncio import logging -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from ably.realtime.connection import ConnectionState from ably.rest.channel import Channel from ably.rest.channel import Channels as RestChannels from ably.transport.websockettransport import ProtocolMessageAction +from ably.types.channeloptions import ChannelOptions from ably.types.channelstate import ChannelState, ChannelStateChange from ably.types.flags import Flag, has_flag from ably.types.message import Message, MessageAction, MessageVersion @@ -20,75 +21,10 @@ if TYPE_CHECKING: from ably.realtime.realtime import AblyRealtime - from ably.util.crypto import CipherParams log = logging.getLogger(__name__) -class ChannelOptions: - """Channel options for Ably Realtime channels - - Attributes - ---------- - cipher : CipherParams, optional - Requests encryption for this channel when not null, and specifies encryption-related parameters. - params : Dict[str, str], optional - Channel parameters that configure the behavior of the channel. - """ - - def __init__(self, cipher: CipherParams | None = None, params: dict | None = None): - self.__cipher = cipher - self.__params = params - # Validate params - if self.__params and not isinstance(self.__params, dict): - raise AblyException("params must be a dictionary", 40000, 400) - - @property - def cipher(self): - """Get cipher configuration""" - return self.__cipher - - @property - def params(self) -> dict[str, str]: - """Get channel parameters""" - return self.__params - - def __eq__(self, other): - """Check equality with another ChannelOptions instance""" - if not isinstance(other, ChannelOptions): - return False - - return (self.__cipher == other.__cipher and - self.__params == other.__params) - - def __hash__(self): - """Make ChannelOptions hashable""" - return hash(( - self.__cipher, - tuple(sorted(self.__params.items())) if self.__params else None, - )) - - def to_dict(self) -> dict[str, Any]: - """Convert to dictionary representation""" - result = {} - if self.__cipher is not None: - result['cipher'] = self.__cipher - if self.__params: - result['params'] = self.__params - return result - - @classmethod - def from_dict(cls, options_dict: dict[str, Any]) -> ChannelOptions: - """Create ChannelOptions from dictionary""" - if not isinstance(options_dict, dict): - raise AblyException("options must be a dictionary", 40000, 400) - - return cls( - cipher=options_dict.get('cipher'), - params=options_dict.get('params'), - ) - - class RealtimeChannel(EventEmitter, Channel): """ Ably Realtime Channel @@ -139,7 +75,7 @@ def __init__(self, realtime: AblyRealtime, name: str, channel_options: ChannelOp self.__internal_state_emitter = EventEmitter() # Initialize presence for this channel - from ably.realtime.realtimepresence import RealtimePresence + from ably.realtime.presence import RealtimePresence self.__presence = RealtimePresence(self) # Pass channel options as dictionary to parent Channel class diff --git a/ably/realtime/realtimepresence.py b/ably/realtime/presence.py similarity index 99% rename from ably/realtime/realtimepresence.py rename to ably/realtime/presence.py index a7dea6e7..79d73070 100644 --- a/ably/realtime/realtimepresence.py +++ b/ably/realtime/presence.py @@ -20,7 +20,7 @@ from ably.util.exceptions import AblyException if TYPE_CHECKING: - from ably.realtime.realtimechannel import RealtimeChannel + from ably.realtime.channel import RealtimeChannel log = logging.getLogger(__name__) diff --git a/ably/realtime/realtime.py b/ably/realtime/realtime.py index 8e980cd0..69e1e8e0 100644 --- a/ably/realtime/realtime.py +++ b/ably/realtime/realtime.py @@ -2,8 +2,8 @@ import logging from typing import Optional +from ably.realtime.channel import Channels from ably.realtime.connection import Connection, ConnectionState -from ably.realtime.realtimechannel import Channels from ably.rest.rest import AblyRest log = logging.getLogger(__name__) diff --git a/ably/types/channeloptions.py b/ably/types/channeloptions.py new file mode 100644 index 00000000..48e34dfe --- /dev/null +++ b/ably/types/channeloptions.py @@ -0,0 +1,70 @@ +from __future__ import annotations + +from typing import Any + +from ably.util.crypto import CipherParams +from ably.util.exceptions import AblyException + + +class ChannelOptions: + """Channel options for Ably Realtime channels + + Attributes + ---------- + cipher : CipherParams, optional + Requests encryption for this channel when not null, and specifies encryption-related parameters. + params : Dict[str, str], optional + Channel parameters that configure the behavior of the channel. + """ + + def __init__(self, cipher: CipherParams | None = None, params: dict | None = None): + self.__cipher = cipher + self.__params = params + # Validate params + if self.__params and not isinstance(self.__params, dict): + raise AblyException("params must be a dictionary", 40000, 400) + + @property + def cipher(self): + """Get cipher configuration""" + return self.__cipher + + @property + def params(self) -> dict[str, str]: + """Get channel parameters""" + return self.__params + + def __eq__(self, other): + """Check equality with another ChannelOptions instance""" + if not isinstance(other, ChannelOptions): + return False + + return (self.__cipher == other.__cipher and + self.__params == other.__params) + + def __hash__(self): + """Make ChannelOptions hashable""" + return hash(( + self.__cipher, + tuple(sorted(self.__params.items())) if self.__params else None, + )) + + def to_dict(self) -> dict[str, Any]: + """Convert to dictionary representation""" + result = {} + if self.__cipher is not None: + result['cipher'] = self.__cipher + if self.__params: + result['params'] = self.__params + return result + + @classmethod + def from_dict(cls, options_dict: dict[str, Any]) -> ChannelOptions: + """Create ChannelOptions from dictionary""" + if not isinstance(options_dict, dict): + raise AblyException("options must be a dictionary", 40000, 400) + + return cls( + cipher=options_dict.get('cipher'), + params=options_dict.get('params'), + ) diff --git a/test/ably/realtime/realtimechannel_publish_test.py b/test/ably/realtime/realtimechannel_publish_test.py index 47edd9fa..9ecf10f9 100644 --- a/test/ably/realtime/realtimechannel_publish_test.py +++ b/test/ably/realtime/realtimechannel_publish_test.py @@ -2,9 +2,10 @@ import pytest +from ably.realtime.channel import ChannelState from ably.realtime.connection import ConnectionState -from ably.realtime.realtimechannel import ChannelOptions, ChannelState from ably.transport.websockettransport import ProtocolMessageAction +from ably.types.channeloptions import ChannelOptions from ably.types.message import Message from ably.util.crypto import CipherParams from ably.util.exceptions import AblyException, IncompatibleClientIdException diff --git a/test/ably/realtime/realtimechannel_test.py b/test/ably/realtime/realtimechannel_test.py index c5915c64..6d2865f2 100644 --- a/test/ably/realtime/realtimechannel_test.py +++ b/test/ably/realtime/realtimechannel_test.py @@ -2,9 +2,10 @@ import pytest +from ably.realtime.channel import ChannelState, RealtimeChannel from ably.realtime.connection import ConnectionState -from ably.realtime.realtimechannel import ChannelOptions, ChannelState, RealtimeChannel from ably.transport.websockettransport import ProtocolMessageAction +from ably.types.channeloptions import ChannelOptions from ably.types.message import Message from ably.util.exceptions import AblyException from test.ably.testapp import TestApp diff --git a/test/ably/realtime/realtimechannel_vcdiff_test.py b/test/ably/realtime/realtimechannel_vcdiff_test.py index 8175bf06..48a484a9 100644 --- a/test/ably/realtime/realtimechannel_vcdiff_test.py +++ b/test/ably/realtime/realtimechannel_vcdiff_test.py @@ -5,7 +5,7 @@ from ably import AblyVCDiffDecoder from ably.realtime.connection import ConnectionState -from ably.realtime.realtimechannel import ChannelOptions +from ably.types.channeloptions import ChannelOptions from ably.types.options import VCDiffDecoder from test.ably.testapp import TestApp from test.ably.utils import BaseAsyncTestCase, WaitableEvent diff --git a/test/ably/realtime/realtimeresume_test.py b/test/ably/realtime/realtimeresume_test.py index fd03c965..bfe77efa 100644 --- a/test/ably/realtime/realtimeresume_test.py +++ b/test/ably/realtime/realtimeresume_test.py @@ -2,8 +2,8 @@ import pytest +from ably.realtime.channel import ChannelState from ably.realtime.connection import ConnectionState -from ably.realtime.realtimechannel import ChannelState from ably.transport.websockettransport import ProtocolMessageAction from test.ably.testapp import TestApp from test.ably.utils import BaseAsyncTestCase, random_string