Skip to content

Commit

Permalink
Add type hints to customer facing interfaces (#195)
Browse files Browse the repository at this point in the history
* PubNub SDK v9.0.0 release.

---------

Co-authored-by: PubNub Release Bot <[email protected]>
  • Loading branch information
seba-aln and pubnub-release-bot authored Oct 2, 2024
1 parent 0d47e58 commit 686b4f4
Show file tree
Hide file tree
Showing 52 changed files with 1,231 additions and 549 deletions.
21 changes: 17 additions & 4 deletions .pubnub.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: python
version: 8.1.0
version: 9.0.0
schema: 1
scm: github.com/pubnub/python
sdks:
Expand All @@ -18,7 +18,7 @@ sdks:
distributions:
- distribution-type: library
distribution-repository: package
package-name: pubnub-8.1.0
package-name: pubnub-9.0.0
location: https://pypi.org/project/pubnub/
supported-platforms:
supported-operating-systems:
Expand Down Expand Up @@ -97,8 +97,8 @@ sdks:
-
distribution-type: library
distribution-repository: git release
package-name: pubnub-8.1.0
location: https://github.com/pubnub/python/releases/download/v8.1.0/pubnub-8.1.0.tar.gz
package-name: pubnub-9.0.0
location: https://github.com/pubnub/python/releases/download/v9.0.0/pubnub-9.0.0.tar.gz
supported-platforms:
supported-operating-systems:
Linux:
Expand Down Expand Up @@ -169,6 +169,19 @@ sdks:
license-url: https://github.com/aio-libs/aiohttp/blob/master/LICENSE.txt
is-required: Required
changelog:
- date: 2024-10-02
version: v9.0.0
changes:
- type: feature
text: "BREAKING CHANGES: Automatic reconnecting for subscribe with exponential backoff is now enabled by default."
- type: feature
text: "Access manager v2 endpoints (grant and audit) will no longer be supported after December 31, 2024, and will be removed without further notice. Refer to the documentation to learn more."
- type: feature
text: "BREAKING CHANGES: Once used to instantiate PubNub, the configuration object (PNConfiguration instance) becomes immutable. You will receive exceptions if you rely on modifying the configuration after the PubNub instance is created. Refer to the documentation to learn more."
- type: improvement
text: "Type hints for parameters and return values are now added to provide a better developer experience."
- type: improvement
text: "All endpoints are now accessible through the builder pattern and named parameters, providing a more flexible experience suitable for custom solutions."
- date: 2024-08-13
version: v8.1.0
changes:
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## v9.0.0
October 02 2024

#### Added
- BREAKING CHANGES: Automatic reconnecting for subscribe with exponential backoff is now enabled by default.
- Access manager v2 endpoints (grant and audit) will no longer be supported after December 31, 2024, and will be removed without further notice. Refer to the documentation to learn more.
- BREAKING CHANGES: Once used to instantiate PubNub, the configuration object (PNConfiguration instance) becomes immutable. You will receive exceptions if you rely on modifying the configuration after the PubNub instance is created. Refer to the documentation to learn more.

#### Modified
- Type hints for parameters and return values are now added to provide a better developer experience.
- All endpoints are now accessible through the builder pattern and named parameters, providing a more flexible experience suitable for custom solutions.

## v8.1.0
August 13 2024

Expand Down
50 changes: 36 additions & 14 deletions pubnub/endpoints/access/grant_token.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,77 @@
from typing import Union, List, Optional
from pubnub import utils
from pubnub.endpoints.endpoint import Endpoint
from pubnub.errors import PNERR_TTL_MISSING, PNERR_INVALID_META, PNERR_RESOURCES_MISSING
from pubnub.exceptions import PubNubException
from pubnub.enums import HttpMethod, PNOperationType
from pubnub.models.consumer.common import PNStatus
from pubnub.models.consumer.v3.access_manager import PNGrantTokenResult
from pubnub.structures import Envelope


class PNGrantTokenResultEnvelope(Envelope):
result: PNGrantTokenResult
status: PNStatus


class GrantToken(Endpoint):
GRANT_TOKEN_PATH = "/v3/pam/%s/grant"

def __init__(self, pubnub):
def __init__(self, pubnub, channels: Union[str, List[str]] = None, channel_groups: Union[str, List[str]] = None,
users: Union[str, List[str]] = None, spaces: Union[str, List[str]] = None,
authorized_user_id: str = None, ttl: Optional[int] = None, meta: Optional[any] = None):
Endpoint.__init__(self, pubnub)
self._ttl = None
self._meta = None
self._authorized_uuid = None
self._ttl = ttl
self._meta = meta
self._authorized_uuid = authorized_user_id
self._channels = []
if channels:
utils.extend_list(self._channels, channels)
if spaces:
utils.extend_list(self._channels, spaces)

self._groups = []
if channel_groups:
utils.extend_list(self._groups, channel_groups)
self._uuids = []
if users:
utils.extend_list(self._uuids, users)

self._sort_params = True

def ttl(self, ttl):
def ttl(self, ttl: int) -> 'GrantToken':
self._ttl = ttl
return self

def meta(self, meta):
def meta(self, meta: any) -> 'GrantToken':
self._meta = meta
return self

def authorized_uuid(self, uuid):
def authorized_uuid(self, uuid: str) -> 'GrantToken':
self._authorized_uuid = uuid
return self

def authorized_user(self, user):
def authorized_user(self, user) -> 'GrantToken':
self._authorized_uuid = user
return self

def spaces(self, spaces):
def spaces(self, spaces: Union[str, List[str]]) -> 'GrantToken':
self._channels = spaces
return self

def users(self, users):
def users(self, users: Union[str, List[str]]) -> 'GrantToken':
self._uuids = users
return self

def channels(self, channels):
def channels(self, channels: Union[str, List[str]]) -> 'GrantToken':
self._channels = channels
return self

def groups(self, groups):
def groups(self, groups: Union[str, List[str]]) -> 'GrantToken':
self._groups = groups
return self

def uuids(self, uuids):
def uuids(self, uuids: Union[str, List[str]]) -> 'GrantToken':
self._uuids = uuids
return self

Expand Down Expand Up @@ -102,9 +121,12 @@ def validate_params(self):
self.validate_ttl()
self.validate_resources()

def create_response(self, envelope):
def create_response(self, envelope) -> PNGrantTokenResult:
return PNGrantTokenResult.from_json(envelope['data'])

def sync(self) -> PNGrantTokenResultEnvelope:
return PNGrantTokenResultEnvelope(super().sync())

def is_auth_required(self):
return False

Expand Down
12 changes: 11 additions & 1 deletion pubnub/endpoints/access/revoke_token.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
from pubnub.enums import PNOperationType, HttpMethod
from pubnub.endpoints.endpoint import Endpoint
from pubnub.models.consumer.common import PNStatus
from pubnub.models.consumer.v3.access_manager import PNRevokeTokenResult
from pubnub import utils
from pubnub.structures import Envelope


class PNRevokeTokenResultEnvelope(Envelope):
result: PNRevokeTokenResult
status: PNStatus


class RevokeToken(Endpoint):
REVOKE_TOKEN_PATH = "/v3/pam/%s/grant/%s"

def __init__(self, pubnub, token):
def __init__(self, pubnub, token: str):
Endpoint.__init__(self, pubnub)
self.token = token

Expand All @@ -18,6 +25,9 @@ def validate_params(self):
def create_response(self, envelope):
return PNRevokeTokenResult(envelope)

def sync(self) -> PNRevokeTokenResultEnvelope:
return PNRevokeTokenResultEnvelope(super().sync())

def is_auth_required(self):
return False

Expand Down
30 changes: 19 additions & 11 deletions pubnub/endpoints/channel_groups/add_channel_to_channel_group.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
from typing import List, Union
from pubnub import utils
from pubnub.endpoints.endpoint import Endpoint
from pubnub.errors import PNERR_CHANNELS_MISSING, PNERR_GROUP_MISSING
from pubnub.exceptions import PubNubException
from pubnub.enums import HttpMethod, PNOperationType
from pubnub.models.consumer.channel_group import PNChannelGroupsAddChannelResult
from pubnub.models.consumer.common import PNStatus
from pubnub.structures import Envelope


class PNChannelGroupsAddChannelResultEnvelope(Envelope):
result: PNChannelGroupsAddChannelResult
status: PNStatus


class AddChannelToChannelGroup(Endpoint):
# /v1/channel-registration/sub-key/<sub_key>/channel-group/<group_name>?add=ch1,ch2
ADD_PATH = "/v1/channel-registration/sub-key/%s/channel-group/%s"

def __init__(self, pubnub):
def __init__(self, pubnub, channels: Union[str, List[str]] = None, channel_group: str = None):
Endpoint.__init__(self, pubnub)
self._channels = []
self._channel_group = None

def channels(self, channels):
if isinstance(channels, (list, tuple)):
self._channels.extend(channels)
else:
self._channels.extend(utils.split_items(channels))
if channels:
utils.extend_list(self._channels, channels)
self._channel_group = channel_group

def channels(self, channels) -> 'AddChannelToChannelGroup':
utils.extend_list(self._channels, channels)
return self

def channel_group(self, channel_group):
def channel_group(self, channel_group: str) -> 'AddChannelToChannelGroup':
self._channel_group = channel_group

return self

def custom_params(self):
Expand All @@ -50,9 +55,12 @@ def validate_params(self):
def is_auth_required(self):
return True

def create_response(self, envelope):
def create_response(self, envelope) -> PNChannelGroupsAddChannelResult:
return PNChannelGroupsAddChannelResult()

def sync(self) -> PNChannelGroupsAddChannelResultEnvelope:
return PNChannelGroupsAddChannelResultEnvelope(super().sync())

def request_timeout(self):
return self.pubnub.config.non_subscribe_request_timeout

Expand Down
19 changes: 14 additions & 5 deletions pubnub/endpoints/channel_groups/list_channels_in_channel_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,25 @@
from pubnub.exceptions import PubNubException
from pubnub.enums import HttpMethod, PNOperationType
from pubnub.models.consumer.channel_group import PNChannelGroupsListResult
from pubnub.models.consumer.common import PNStatus
from pubnub.structures import Envelope


class PNChannelGroupsListResultEnvelope(Envelope):
result: PNChannelGroupsListResult
status: PNStatus


class ListChannelsInChannelGroup(Endpoint):
# /v1/channel-registration/sub-key/<sub_key>/channel-group/<group_name>
LIST_PATH = "/v1/channel-registration/sub-key/%s/channel-group/%s"

def __init__(self, pubnub):
def __init__(self, pubnub, channel_group: str = None):
Endpoint.__init__(self, pubnub)
self._channel_group = None

def channel_group(self, channel_group):
self._channel_group = channel_group

def channel_group(self, channel_group: str) -> 'ListChannelsInChannelGroup':
self._channel_group = channel_group
return self

def custom_params(self):
Expand All @@ -35,12 +41,15 @@ def validate_params(self):
if not isinstance(self._channel_group, str) or len(self._channel_group) == 0:
raise PubNubException(pn_error=PNERR_GROUP_MISSING)

def create_response(self, envelope):
def create_response(self, envelope) -> PNChannelGroupsListResult:
if 'payload' in envelope and 'channels' in envelope['payload']:
return PNChannelGroupsListResult(envelope['payload']['channels'])
else:
return PNChannelGroupsListResult([])

def sync(self) -> PNChannelGroupsListResultEnvelope:
return PNChannelGroupsListResultEnvelope(super().sync())

def is_auth_required(self):
return True

Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
from typing import List, Union
from pubnub import utils
from pubnub.endpoints.endpoint import Endpoint
from pubnub.errors import PNERR_CHANNELS_MISSING, PNERR_GROUP_MISSING
from pubnub.exceptions import PubNubException
from pubnub.enums import HttpMethod, PNOperationType
from pubnub.models.consumer.channel_group import PNChannelGroupsRemoveChannelResult
from pubnub.models.consumer.common import PNStatus
from pubnub.structures import Envelope


class PNChannelGroupsRemoveChannelResultEnvelope(Envelope):
result: PNChannelGroupsRemoveChannelResult
status: PNStatus


class RemoveChannelFromChannelGroup(Endpoint):
# /v1/channel-registration/sub-key/<sub_key>/channel-group/<group_name>?remove=ch1,ch2
REMOVE_PATH = "/v1/channel-registration/sub-key/%s/channel-group/%s"
_channels: list = []
_channel_group: str = None

def __init__(self, pubnub):
def __init__(self, pubnub, channels: Union[str, List[str]] = None, channel_group: str = None):
Endpoint.__init__(self, pubnub)
self._channels = []
self._channel_group = None

def channels(self, channels):
if isinstance(channels, (list, tuple)):
self._channels.extend(channels)
else:
self._channels.extend(utils.split_items(channels))
if channels:
utils.extend_list(self._channels, channels)
self._channel_group = channel_group

def channels(self, channels) -> 'RemoveChannelFromChannelGroup':
utils.extend_list(self._channels, channels)
return self

def channel_group(self, channel_group):
def channel_group(self, channel_group: str) -> 'RemoveChannelFromChannelGroup':
self._channel_group = channel_group

return self

def custom_params(self):
Expand All @@ -50,9 +57,12 @@ def validate_params(self):
def is_auth_required(self):
return True

def create_response(self, envelope):
def create_response(self, envelope) -> PNChannelGroupsRemoveChannelResult:
return PNChannelGroupsRemoveChannelResult()

def sync(self) -> PNChannelGroupsRemoveChannelResultEnvelope:
return PNChannelGroupsRemoveChannelResultEnvelope(super().sync())

def request_timeout(self):
return self.pubnub.config.non_subscribe_request_timeout

Expand Down
Loading

0 comments on commit 686b4f4

Please sign in to comment.