Skip to content

Commit d88b9a7

Browse files
Merge pull request #88 from stefan-qsd/develop
APNS2 push support
2 parents 99055dd + edf9639 commit d88b9a7

14 files changed

+250
-23
lines changed

.pubnub.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
name: python
2-
version: 4.3.0
2+
version: 4.4.0
33
schema: 1
44
scm: github.com/pubnub/python
55
changelog:
6+
- version: v4.4.0
7+
date: Feb 20, 2020
8+
changes:
9+
- type: feature
10+
text: Add support for APNS2 Push API
611
- version: v4.3.0
712
date: Jan 28, 2020
813
changes:
@@ -178,11 +183,18 @@ features:
178183
- CHANNEL-GROUPS-REMOVE-CHANNELS
179184
- CHANNEL-GROUPS-REMOVE-GROUPS
180185
- CHANNEL-GROUPS-LIST-CHANNELS-IN-GROUP
186+
others:
187+
- TELEMETRY
188+
- CREATE-PUSH-PAYLOAD
181189
push:
182190
- PUSH-ADD-DEVICE-TO-CHANNELS
183191
- PUSH-REMOVE-DEVICE-FROM-CHANNELS
184192
- PUSH-LIST-CHANNELS-FROM-DEVICE
185193
- PUSH-REMOVE-DEVICE
194+
- PUSH-TYPE-APNS
195+
- PUSH-TYPE-APNS2
196+
- PUSH-TYPE-FCM
197+
- PUSH-TYPE-MPNS
186198
presence:
187199
- PRESENCE-HERE-NOW
188200
- PRESENCE-WHERE-NOW

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## [4.4.0](https://github.com/pubnub/python/tree/v4.4.0)
2+
3+
[Full Changelog](https://github.com/pubnub/python/compare/v4.3.0...v4.4.0)
4+
5+
- 🌟 Add support for APNS2 Push API
6+
17
## [4.3.0](https://github.com/pubnub/python/tree/v4.3.0)
28

39
[Full Changelog](https://github.com/pubnub/python/compare/v4.2.1...v4.3.0)

pubnub/endpoints/push/add_channels_to_push.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
import six
22

33
from pubnub.endpoints.endpoint import Endpoint
4-
from pubnub.errors import PNERR_CHANNEL_MISSING, PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING
4+
from pubnub.errors import PNERR_CHANNEL_MISSING, PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING, \
5+
PNERR_PUSH_TOPIC_MISSING
56
from pubnub.exceptions import PubNubException
6-
from pubnub.enums import HttpMethod, PNOperationType
7+
from pubnub.enums import HttpMethod, PNOperationType, PNPushType, PNPushEnvironment
78
from pubnub.models.consumer.push import PNPushAddChannelResult
89
from pubnub import utils
910

1011

1112
class AddChannelsToPush(Endpoint):
1213
# v1/push/sub-key/{subKey}/devices/{pushToken}
1314
ADD_PATH = "/v1/push/sub-key/%s/devices/%s"
15+
# v2/push/sub-key/{subKey}/devices-apns2/{deviceApns2}
16+
ADD_PATH_APNS2 = "/v2/push/sub-key/%s/devices-apns2/%s"
1417

1518
def __init__(self, pubnub):
1619
Endpoint.__init__(self, pubnub)
1720
self._channels = None
1821
self._device_id = None
1922
self._push_type = None
23+
self._topic = None
24+
self._environment = None
2025

2126
def channels(self, channels):
2227
self._channels = channels
@@ -30,17 +35,37 @@ def push_type(self, push_type):
3035
self._push_type = push_type
3136
return self
3237

38+
def topic(self, topic):
39+
self._topic = topic
40+
return self
41+
42+
def environment(self, environment):
43+
self._environment = environment
44+
return self
45+
3346
def custom_params(self):
3447
params = {}
3548

3649
params['add'] = utils.join_items(self._channels)
37-
params['type'] = utils.push_type_to_string(self._push_type)
50+
51+
if self._push_type != PNPushType.APNS2:
52+
params['type'] = utils.push_type_to_string(self._push_type)
53+
else:
54+
if self._environment is None:
55+
self._environment = PNPushEnvironment.DEVELOPMENT
56+
57+
params['environment'] = self._environment
58+
params['topic'] = self._topic
3859

3960
return params
4061

4162
def build_path(self):
42-
return AddChannelsToPush.ADD_PATH % (
43-
self.pubnub.config.subscribe_key, self._device_id)
63+
if self._push_type != PNPushType.APNS2:
64+
return AddChannelsToPush.ADD_PATH % (
65+
self.pubnub.config.subscribe_key, self._device_id)
66+
else:
67+
return AddChannelsToPush.ADD_PATH_APNS2 % (
68+
self.pubnub.config.subscribe_key, self._device_id)
4469

4570
def http_method(self):
4671
return HttpMethod.GET
@@ -57,6 +82,10 @@ def validate_params(self):
5782
if self._push_type is None:
5883
raise PubNubException(pn_error=PNERROR_PUSH_TYPE_MISSING)
5984

85+
if self._push_type == PNPushType.APNS2:
86+
if not isinstance(self._topic, six.string_types) or len(self._topic) == 0:
87+
raise PubNubException(pn_error=PNERR_PUSH_TOPIC_MISSING)
88+
6089
def create_response(self, envelope):
6190
return PNPushAddChannelResult()
6291

pubnub/endpoints/push/list_push_provisions.py

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
import six
22

33
from pubnub.endpoints.endpoint import Endpoint
4-
from pubnub.errors import PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING
4+
from pubnub.errors import PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING, PNERR_PUSH_TOPIC_MISSING
55
from pubnub.exceptions import PubNubException
6-
from pubnub.enums import HttpMethod, PNOperationType
6+
from pubnub.enums import HttpMethod, PNOperationType, PNPushType, PNPushEnvironment
77
from pubnub.models.consumer.push import PNPushListProvisionsResult
88
from pubnub import utils
99

1010

1111
class ListPushProvisions(Endpoint):
1212
# v1/push/sub-key/{subKey}/devices/{pushToken}
1313
LIST_PATH = "/v1/push/sub-key/%s/devices/%s"
14+
# v2/push/sub-key/{subKey}/devices-apns2/{deviceApns2}
15+
LIST_PATH_APNS2 = "/v2/push/sub-key/%s/devices-apns2/%s"
1416

1517
def __init__(self, pubnub):
1618
Endpoint.__init__(self, pubnub)
1719
self._device_id = None
1820
self._push_type = None
21+
self._topic = None
22+
self._environment = None
1923

2024
def device_id(self, device_id):
2125
self._device_id = device_id
@@ -25,16 +29,35 @@ def push_type(self, push_type):
2529
self._push_type = push_type
2630
return self
2731

32+
def topic(self, topic):
33+
self._topic = topic
34+
return self
35+
36+
def environment(self, environment):
37+
self._environment = environment
38+
return self
39+
2840
def custom_params(self):
2941
params = {}
3042

31-
params['type'] = utils.push_type_to_string(self._push_type)
43+
if self._push_type != PNPushType.APNS2:
44+
params['type'] = utils.push_type_to_string(self._push_type)
45+
else:
46+
if self._environment is None:
47+
self._environment = PNPushEnvironment.DEVELOPMENT
48+
49+
params['environment'] = self._environment
50+
params['topic'] = self._topic
3251

3352
return params
3453

3554
def build_path(self):
36-
return ListPushProvisions.LIST_PATH % (
37-
self.pubnub.config.subscribe_key, self._device_id)
55+
if self._push_type != PNPushType.APNS2:
56+
return ListPushProvisions.LIST_PATH % (
57+
self.pubnub.config.subscribe_key, self._device_id)
58+
else:
59+
return ListPushProvisions.LIST_PATH_APNS2 % (
60+
self.pubnub.config.subscribe_key, self._device_id)
3861

3962
def http_method(self):
4063
return HttpMethod.GET
@@ -48,6 +71,10 @@ def validate_params(self):
4871
if self._push_type is None:
4972
raise PubNubException(pn_error=PNERROR_PUSH_TYPE_MISSING)
5073

74+
if self._push_type == PNPushType.APNS2:
75+
if not isinstance(self._topic, six.string_types) or len(self._topic) == 0:
76+
raise PubNubException(pn_error=PNERR_PUSH_TOPIC_MISSING)
77+
5178
def create_response(self, channels):
5279
if channels is not None and len(channels) > 0 and isinstance(channels, list):
5380
return PNPushListProvisionsResult(channels)

pubnub/endpoints/push/remove_channels_from_push.py

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
import six
22

33
from pubnub.endpoints.endpoint import Endpoint
4-
from pubnub.errors import PNERR_CHANNEL_MISSING, PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING
4+
from pubnub.errors import PNERR_CHANNEL_MISSING, PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING, \
5+
PNERR_PUSH_TOPIC_MISSING
56
from pubnub.exceptions import PubNubException
6-
from pubnub.enums import HttpMethod, PNOperationType
7+
from pubnub.enums import HttpMethod, PNOperationType, PNPushType, PNPushEnvironment
78
from pubnub.models.consumer.push import PNPushRemoveChannelResult
89
from pubnub import utils
910

1011

1112
class RemoveChannelsFromPush(Endpoint):
1213
# v1/push/sub-key/{subKey}/devices/{pushToken}
1314
REMOVE_PATH = "/v1/push/sub-key/%s/devices/%s"
15+
# v2/push/sub-key/{subKey}/devices-apns2/{deviceApns2}
16+
REMOVE_PATH_APNS2 = "/v2/push/sub-key/%s/devices-apns2/%s"
1417

1518
def __init__(self, pubnub):
1619
Endpoint.__init__(self, pubnub)
1720
self._channels = None
1821
self._device_id = None
1922
self._push_type = None
23+
self._topic = None
24+
self._environment = None
2025

2126
def channels(self, channels):
2227
self._channels = channels
@@ -30,14 +35,35 @@ def push_type(self, push_type):
3035
self._push_type = push_type
3136
return self
3237

38+
def topic(self, topic):
39+
self._topic = topic
40+
return self
41+
42+
def environment(self, environment):
43+
self._environment = environment
44+
return self
45+
3346
def custom_params(self):
34-
params = {'remove': utils.join_items(self._channels), 'type': utils.push_type_to_string(self._push_type)}
47+
params = {'remove': utils.join_items(self._channels)}
48+
49+
if self._push_type != PNPushType.APNS2:
50+
params['type'] = utils.push_type_to_string(self._push_type)
51+
else:
52+
if self._environment is None:
53+
self._environment = PNPushEnvironment.DEVELOPMENT
54+
55+
params['environment'] = self._environment
56+
params['topic'] = self._topic
3557

3658
return params
3759

3860
def build_path(self):
39-
return RemoveChannelsFromPush.REMOVE_PATH % (
40-
self.pubnub.config.subscribe_key, self._device_id)
61+
if self._push_type != PNPushType.APNS2:
62+
return RemoveChannelsFromPush.REMOVE_PATH % (
63+
self.pubnub.config.subscribe_key, self._device_id)
64+
else:
65+
return RemoveChannelsFromPush.REMOVE_PATH_APNS2 % (
66+
self.pubnub.config.subscribe_key, self._device_id)
4167

4268
def http_method(self):
4369
return HttpMethod.GET
@@ -54,6 +80,10 @@ def validate_params(self):
5480
if self._push_type is None:
5581
raise PubNubException(pn_error=PNERROR_PUSH_TYPE_MISSING)
5682

83+
if self._push_type == PNPushType.APNS2:
84+
if not isinstance(self._topic, six.string_types) or len(self._topic) == 0:
85+
raise PubNubException(pn_error=PNERR_PUSH_TOPIC_MISSING)
86+
5787
def create_response(self, envelope):
5888
return PNPushRemoveChannelResult()
5989

pubnub/endpoints/push/remove_device.py

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
import six
22

33
from pubnub.endpoints.endpoint import Endpoint
4-
from pubnub.errors import PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING
4+
from pubnub.errors import PNERR_PUSH_DEVICE_MISSING, PNERROR_PUSH_TYPE_MISSING, PNERR_PUSH_TOPIC_MISSING
55
from pubnub.exceptions import PubNubException
6-
from pubnub.enums import HttpMethod, PNOperationType
6+
from pubnub.enums import HttpMethod, PNOperationType, PNPushType, PNPushEnvironment
77
from pubnub.models.consumer.push import PNPushRemoveAllChannelsResult
88
from pubnub import utils
99

1010

1111
class RemoveDeviceFromPush(Endpoint):
1212
# v1/push/sub-key/{subKey}/devices/{pushToken}/remove
1313
REMOVE_PATH = "/v1/push/sub-key/%s/devices/%s/remove"
14+
# v2/push/sub-key/{subKey}/devices-apns2/{deviceApns2}/remove
15+
REMOVE_PATH_APNS2 = "/v2/push/sub-key/%s/devices-apns2/%s/remove"
1416

1517
def __init__(self, pubnub):
1618
Endpoint.__init__(self, pubnub)
1719
self._device_id = None
1820
self._push_type = None
21+
self._topic = None
22+
self._environment = None
1923

2024
def device_id(self, device_id):
2125
self._device_id = device_id
@@ -25,16 +29,35 @@ def push_type(self, push_type):
2529
self._push_type = push_type
2630
return self
2731

32+
def topic(self, topic):
33+
self._topic = topic
34+
return self
35+
36+
def environment(self, environment):
37+
self._environment = environment
38+
return self
39+
2840
def custom_params(self):
2941
params = {}
3042

31-
params['type'] = utils.push_type_to_string(self._push_type)
43+
if self._push_type != PNPushType.APNS2:
44+
params['type'] = utils.push_type_to_string(self._push_type)
45+
else:
46+
if self._environment is None:
47+
self._environment = PNPushEnvironment.DEVELOPMENT
48+
49+
params['environment'] = self._environment
50+
params['topic'] = self._topic
3251

3352
return params
3453

3554
def build_path(self):
36-
return RemoveDeviceFromPush.REMOVE_PATH % (
37-
self.pubnub.config.subscribe_key, self._device_id)
55+
if self._push_type != PNPushType.APNS2:
56+
return RemoveDeviceFromPush.REMOVE_PATH % (
57+
self.pubnub.config.subscribe_key, self._device_id)
58+
else:
59+
return RemoveDeviceFromPush.REMOVE_PATH_APNS2 % (
60+
self.pubnub.config.subscribe_key, self._device_id)
3861

3962
def http_method(self):
4063
return HttpMethod.GET
@@ -48,6 +71,10 @@ def validate_params(self):
4871
if self._push_type is None:
4972
raise PubNubException(pn_error=PNERROR_PUSH_TYPE_MISSING)
5073

74+
if self._push_type == PNPushType.APNS2:
75+
if not isinstance(self._topic, six.string_types) or len(self._topic) == 0:
76+
raise PubNubException(pn_error=PNERR_PUSH_TOPIC_MISSING)
77+
5178
def create_response(self, envelope):
5279
return PNPushRemoveAllChannelsResult()
5380

pubnub/enums.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class PNPushType(object):
103103
APNS = 1
104104
MPNS = 2
105105
GCM = 3
106+
APNS2 = 4
106107

107108

108109
class PNResourceType(object):
@@ -115,3 +116,8 @@ class PNResourceType(object):
115116
class PNMatchType(object):
116117
RESOURCE = "resource"
117118
PATTERN = "pattern"
119+
120+
121+
class PNPushEnvironment(object):
122+
DEVELOPMENT = "development"
123+
PRODUCTION = "production"

pubnub/errors.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@
4141
PNERR_HISTORY_MESSAGE_ACTIONS_MULTIPLE_CHANNELS = "History can return message action data for a single channel only. " \
4242
"Either pass a single channel or disable the include_message_action" \
4343
"s flag. "
44+
45+
PNERR_PUSH_TOPIC_MISSING = "Push notification topic is missing. Required only if push type is APNS2."

pubnub/pubnub_core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656

5757
class PubNubCore:
5858
"""A base class for PubNub Python API implementations"""
59-
SDK_VERSION = "4.3.0"
59+
SDK_VERSION = "4.4.0"
6060
SDK_NAME = "PubNub-Python"
6161

6262
TIMESTAMP_DIVIDER = 1000

0 commit comments

Comments
 (0)