Skip to content

Commit cf8cbed

Browse files
Sebastian Molendapubnub-release-bot
andauthored
Feat/listeners (#186)
* PubNub Entrypoint * Fixes from tests. * Listeners * Refactor names, add SubscriptionSet, remove debug * Event engine as a default subscription manager * Update runner * move tt, tr and with_presence to subscribe method * Rework subscriptionSet to use PubNubSubscriptions * remove type from subscriptionset * Fixed subscription set and examples * Add subscription set and subscription item level listeners * Fix in example * PubNub SDK v8.0.0 release. --------- Co-authored-by: PubNub Release Bot <120067856+pubnub-release-bot@users.noreply.github.com>
1 parent 7053332 commit cf8cbed

File tree

26 files changed

+961
-159
lines changed

26 files changed

+961
-159
lines changed

.github/workflows/run-tests.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ defaults:
1010
run:
1111
shell: bash
1212
env:
13-
PN_KEY_PUBLISH: ${{ secrets.PN_KEY_PUBLISH }}
14-
PN_KEY_SUBSCRIBE: ${{ secrets.PN_KEY_SUBSCRIBE }}
15-
PN_KEY_SECRET: ${{ secrets.PN_KEY_SECRET }}
16-
PN_KEY_PAM_PUBLISH: ${{ secrets.PN_KEY_PAM_PUBLISH }}
17-
PN_KEY_PAM_SUBSCRIBE: ${{ secrets.PN_KEY_PAM_SUBSCRIBE }}
18-
PN_KEY_PAM_SECRET: ${{ secrets.PN_KEY_PAM_SECRET }}
13+
PN_KEY_PUBLISH: ${{ secrets.SDK_PUB_KEY }}
14+
PN_KEY_SUBSCRIBE: ${{ secrets.SDK_SUB_KEY }}
15+
PN_KEY_SECRET: ${{ secrets.SDK_SEC_KEY }}
16+
PN_KEY_PAM_PUBLISH: ${{ secrets.SDK_PAM_PUB_KEY }}
17+
PN_KEY_PAM_SUBSCRIBE: ${{ secrets.SDK_PAM_SUB_KEY }}
18+
PN_KEY_PAM_SECRET: ${{ secrets.SDK_PAM_SEC_KEY }}
1919

2020
jobs:
2121
tests:

.pubnub.yml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: python
2-
version: 7.4.4
2+
version: 8.0.0
33
schema: 1
44
scm: github.com/pubnub/python
55
sdks:
@@ -18,7 +18,7 @@ sdks:
1818
distributions:
1919
- distribution-type: library
2020
distribution-repository: package
21-
package-name: pubnub-7.4.4
21+
package-name: pubnub-8.0.0
2222
location: https://pypi.org/project/pubnub/
2323
supported-platforms:
2424
supported-operating-systems:
@@ -97,8 +97,8 @@ sdks:
9797
-
9898
distribution-type: library
9999
distribution-repository: git release
100-
package-name: pubnub-7.4.4
101-
location: https://github.com/pubnub/python/releases/download/v7.4.4/pubnub-7.4.4.tar.gz
100+
package-name: pubnub-8.0.0
101+
location: https://github.com/pubnub/python/releases/download/v8.0.0/pubnub-8.0.0.tar.gz
102102
supported-platforms:
103103
supported-operating-systems:
104104
Linux:
@@ -169,6 +169,13 @@ sdks:
169169
license-url: https://github.com/aio-libs/aiohttp/blob/master/LICENSE.txt
170170
is-required: Required
171171
changelog:
172+
- date: 2024-05-09
173+
version: v8.0.0
174+
changes:
175+
- type: feature
176+
text: "A new version of subscription and presence handling is enabled by default (enableEventEngine flag is set to true). Please consult the documentation for new PNStatus values that are emitted for subscriptions, as code changes might be required to support this change."
177+
- type: feature
178+
text: "Channels, ChannelGroups, ChannelMetadata and UserMetadata."
172179
- date: 2024-04-10
173180
version: v7.4.4
174181
changes:

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## v8.0.0
2+
May 09 2024
3+
4+
#### Added
5+
- A new version of subscription and presence handling is enabled by default (enableEventEngine flag is set to true). Please consult the documentation for new PNStatus values that are emitted for subscriptions, as code changes might be required to support this change.
6+
- Channels, ChannelGroups, ChannelMetadata and UserMetadata.
7+
18
## v7.4.4
29
April 10 2024
310

examples/subscription_object.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import time
2+
3+
from os import getenv
4+
from pubnub.callbacks import SubscribeCallback
5+
from pubnub.pnconfiguration import PNConfiguration
6+
from pubnub.pubnub import PubNub
7+
8+
9+
# Listeners declaration
10+
def on_message(listener):
11+
def message_callback(message):
12+
print(f"\033[94mMessage received on: {listener}: \n{message.message}\033[0m\n")
13+
return message_callback
14+
15+
16+
def on_message_action(listener):
17+
def message_callback(message_action):
18+
print(f"\033[5mMessageAction received on: {listener}: \n{message_action.value}\033[0m\n")
19+
return message_callback
20+
21+
22+
def on_presence(listener):
23+
def presence_callback(presence):
24+
print(f"\033[0;32mPresence received on: {listener}: \t{presence.uuid} {presence.event}s "
25+
f"{presence.subscription or presence.channel}\033[0m")
26+
return presence_callback
27+
28+
29+
def on_status(listener):
30+
def status_callback(status):
31+
print(f"\033[92mStatus received on: {listener}: \t{status.category.name}\033[0m")
32+
return status_callback
33+
34+
35+
def on_signal(listener):
36+
def signal_callback(signal):
37+
print(f"\033[0;36mSignal received on: {listener}: \n{signal.publisher} says: \t{signal.message}\033[0m")
38+
return signal_callback
39+
40+
41+
def on_channel_metadata(listener):
42+
def channel_metadata_callback(channel_meta):
43+
print(f"\033[0;36mChannel metadata received on: {listener}: \n{channel_meta.__dict__}\033[0m")
44+
return channel_metadata_callback
45+
46+
47+
class PrintListener(SubscribeCallback):
48+
def status(self, _, status):
49+
print(f'\033[92mPrintListener.status:\n{status.category.name}\033[0m')
50+
51+
def message(self, _, message):
52+
print(f'\033[94mPrintListener.message:\n{message.message}\033[0m')
53+
54+
def presence(self, _, presence):
55+
print(f'PrintListener.presence:\n{presence.uuid} {presence.event}s '
56+
f'{presence.subscription or presence.channel}\033[0m')
57+
58+
def signal(self, _, signal):
59+
print(f'PrintListener.signal:\n{signal.message} from {signal.publisher}\033[0m')
60+
61+
def channel(self, _, channel):
62+
print(f'\033[0;37mChannel Meta:\n{channel.__dict__}\033[0m')
63+
64+
def uuid(self, _, uuid):
65+
print(f'User Meta:\n{uuid.__dict__}\033[0m')
66+
67+
def membership(self, _, membership):
68+
print(f'Membership:\n{membership.__dict__}\033[0m')
69+
70+
def message_action(self, _, message_action):
71+
print(f'PrintListener.message_action {message_action}\033[0m')
72+
73+
def file(self, _, file_message):
74+
print(f' {file_message.__dict__}\033[0m')
75+
76+
77+
channel = 'test'
78+
group_name = 'test-group'
79+
80+
config = PNConfiguration()
81+
config.subscribe_key = getenv("PN_KEY_SUBSCRIBE")
82+
config.publish_key = getenv("PN_KEY_PUBLISH")
83+
config.user_id = "example"
84+
config.enable_subscribe = True
85+
config.daemon = True
86+
87+
pubnub = PubNub(config)
88+
pubnub.add_listener(PrintListener())
89+
90+
# Subscribing
91+
92+
# Channel test, no presence, first channel object
93+
print('Creating channel object for "test"')
94+
test1 = pubnub.channel(f'{channel}')
95+
print('Creating subscription object for "test"')
96+
t1_subscription = test1.subscription(with_presence=True)
97+
t1_subscription.on_message = on_message('listener_1')
98+
t1_subscription.on_message_action = on_message_action('listener_1')
99+
t1_subscription.on_presence = on_presence('listener_1')
100+
t1_subscription.on_status = on_status('listener_1')
101+
t1_subscription.on_signal = on_signal('listener_1')
102+
103+
print('We\'re not yet subscribed to channel "test". So let\'s do it now.')
104+
t1_subscription.subscribe()
105+
print("Now we're subscribed. We should receive status: connected")
106+
107+
# Testing message delivery
108+
publish_result = pubnub.publish() \
109+
.channel(f'{channel}') \
110+
.message('Hello channel "test" from PubNub Python SDK') \
111+
.meta({'lang': 'en'}) \
112+
.sync()
113+
114+
time.sleep(2)
115+
116+
print('Removing subscription object for "test"')
117+
t1_subscription.unsubscribe()
118+
time.sleep(2)
119+
120+
print('Exiting')
121+
pubnub.stop()
122+
exit(0)
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
import time
2+
3+
from os import getenv
4+
from pubnub.callbacks import SubscribeCallback
5+
from pubnub.pnconfiguration import PNConfiguration
6+
from pubnub.pubnub import PubNub
7+
8+
9+
# Listeners declaration
10+
def on_message(listener):
11+
def message_callback(message):
12+
print(f"\033[94mMessage received on: {listener}: \n{message.message}\033[0m\n")
13+
return message_callback
14+
15+
16+
def on_message_action(listener):
17+
def message_callback(message_action):
18+
print(f"\033[5mMessageAction received on: {listener}: \n{message_action.value}\033[0m\n")
19+
return message_callback
20+
21+
22+
def on_presence(listener):
23+
def presence_callback(presence):
24+
print(f"\033[0;32mPresence received on: {listener}: \t{presence.uuid} {presence.event}s "
25+
f"{presence.subscription or presence.channel}\033[0m")
26+
return presence_callback
27+
28+
29+
def on_status(listener):
30+
def status_callback(status):
31+
print(f"\033[92mStatus received on: {listener}: \t{status.category.name}\033[0m")
32+
return status_callback
33+
34+
35+
def on_signal(listener):
36+
def signal_callback(signal):
37+
print(f"\033[0;36mSignal received on: {listener}: \n{signal.publisher} says: \t{signal.message}\033[0m")
38+
return signal_callback
39+
40+
41+
def on_channel_metadata(listener):
42+
def channel_metadata_callback(channel_meta):
43+
print(f"\033[0;36mChannel metadata received on: {listener}: \n{channel_meta.__dict__}\033[0m")
44+
return channel_metadata_callback
45+
46+
47+
class PrintListener(SubscribeCallback):
48+
def status(self, _, status):
49+
print(f'\033[92mPrintListener.status:\n{status.category.name}\033[0m')
50+
51+
def message(self, _, message):
52+
print(f'\033[94mPrintListener.message:\n{message.message}\033[0m')
53+
54+
def presence(self, _, presence):
55+
print(f'PrintListener.presence:\n{presence.uuid} {presence.event}s '
56+
f'{presence.subscription or presence.channel}\033[0m')
57+
58+
def signal(self, _, signal):
59+
print(f'PrintListener.signal:\n{signal.message} from {signal.publisher}\033[0m')
60+
61+
def channel(self, _, channel):
62+
print(f'\033[0;37mChannel Meta:\n{channel.__dict__}\033[0m')
63+
64+
def uuid(self, _, uuid):
65+
print(f'User Meta:\n{uuid.__dict__}\033[0m')
66+
67+
def membership(self, _, membership):
68+
print(f'Membership:\n{membership.__dict__}\033[0m')
69+
70+
def message_action(self, _, message_action):
71+
print(f'PrintListener.message_action {message_action}\033[0m')
72+
73+
def file(self, _, file_message):
74+
print(f' {file_message.__dict__}\033[0m')
75+
76+
77+
channel = 'test'
78+
group_name = 'test-group'
79+
80+
config = PNConfiguration()
81+
config.subscribe_key = getenv("PN_KEY_SUBSCRIBE")
82+
config.publish_key = getenv("PN_KEY_PUBLISH")
83+
config.user_id = "example"
84+
config.enable_subscribe = True
85+
config.daemon = True
86+
87+
pubnub = PubNub(config)
88+
pubnub.add_listener(PrintListener())
89+
90+
# Subscribing
91+
92+
# Channel test, no presence, first channel object
93+
print('Creating channel object for "test"')
94+
test1 = pubnub.channel(f'{channel}')
95+
print('Creating subscription object for "test"')
96+
t1_subscription = test1.subscription(with_presence=False)
97+
t1_subscription.on_message = on_message('listener_1')
98+
t1_subscription.on_message_action = on_message_action('listener_1')
99+
t1_subscription.on_presence = on_presence('listener_1')
100+
t1_subscription.on_status = on_status('listener_1')
101+
t1_subscription.on_signal = on_signal('listener_1')
102+
103+
print('We\'re not yet subscribed to channel "test". So let\'s do it now.')
104+
t1_subscription.subscribe()
105+
print("Now we're subscribed. We should receive status: connected")
106+
107+
time.sleep(3)
108+
print("We don't see any presence event since we don't have it enabled yet")
109+
110+
print('Creating second subscription object for channel "test.2"')
111+
test2 = pubnub.channel(f'{channel}.2')
112+
print('Creating subscription object for "test"')
113+
t2_subscription = test1.subscription(with_presence=True)
114+
115+
t2_subscription.on_message = on_message('listener_2')
116+
t2_subscription.on_presence = on_presence('listener_2')
117+
t2_subscription.on_status = on_status('listener_2')
118+
t2_subscription.on_signal = on_signal('listener_2')
119+
t2_subscription.subscribe()
120+
121+
print('Now we\'re subscribed to "test" with two listeners. one with presence and one without')
122+
print('So we should see presence events only for listener "test2" for channel "test2"')
123+
time.sleep(2)
124+
125+
# Channel test3, no presence, third channel object
126+
print('Creating channel object for "test.3"')
127+
test3 = pubnub.channel(f'{channel}.3')
128+
print('Creating subscription object for "test.3"')
129+
t3_subscription = test3.subscription()
130+
t3_subscription.on_message = on_message('listener_3')
131+
t3_subscription.on_presence = on_presence('listener_3')
132+
t3_subscription.on_status = on_status('listener_3')
133+
t3_subscription.on_signal = on_signal('listener_3')
134+
print('We subscribe to third channel so we should see three "connected" statuses and no new presence events')
135+
t3_subscription.subscribe()
136+
137+
print('Creating wildcard object for "test.*"')
138+
wildcard_channel = pubnub.channel(f'{channel}.*')
139+
print('Creating wildcard subscription object for "test.*"')
140+
wildcard = wildcard_channel.subscription()
141+
wildcard.on_message = on_message('WILDCARD')
142+
wildcard.on_presence = on_presence('WILDCARD')
143+
wildcard.on_status = on_status('WILDCARD')
144+
wildcard.on_signal = on_signal('WILDCARD')
145+
print('We subscribe to all channels "test.*"')
146+
wildcard.subscribe()
147+
148+
print('Creating Group with "test.2" and "test.3"')
149+
pubnub.add_channel_to_channel_group() \
150+
.channels(['test']) \
151+
.channel_group(group_name) \
152+
.sync()
153+
154+
print('Creating group object for "test_group"')
155+
group = pubnub.channel_group(f'{group_name}')
156+
print('Creating wildcard subscription object for "group_name"')
157+
group_subscription = group.subscription()
158+
group_subscription.on_message = on_message('group')
159+
group_subscription.on_presence = on_presence('group')
160+
group_subscription.on_status = on_status('group')
161+
group_subscription.on_signal = on_signal('group')
162+
print('We subscribe to the channel group "test_group"')
163+
group_subscription.subscribe()
164+
165+
print('Now we publish messages to each channel separately')
166+
time.sleep(1)
167+
168+
# Testing message delivery
169+
publish_result = pubnub.publish() \
170+
.channel(f'{channel}') \
171+
.message('Hello channel "test" from PubNub Python SDK') \
172+
.meta({'lang': 'en'}) \
173+
.sync()
174+
175+
pubnub.publish() \
176+
.channel(f'{channel}.2') \
177+
.message('Nau mai ki te hongere "test.2" mai i PubNub Python SDK') \
178+
.meta({'lang': 'mi'}) \
179+
.sync()
180+
181+
pubnub.publish() \
182+
.channel(f'{channel}.3') \
183+
.message('Bienvenido al canal "test.3" de PubNub Python SDK') \
184+
.meta({'lang': 'es'}) \
185+
.sync()
186+
187+
pubnub.publish() \
188+
.channel(f'{channel}.4') \
189+
.message('Ciao canale "test.4" da PubNub Python SDK') \
190+
.meta({'lang': 'it'}) \
191+
.sync()
192+
193+
time.sleep(1)
194+
195+
print('Removing second subscription object for "test"')
196+
t1_subscription.unsubscribe()
197+
198+
print('Exiting')
199+
pubnub.stop()
200+
exit(0)

0 commit comments

Comments
 (0)