Skip to content

Commit 2941205

Browse files
seba-alnClient Engineering Bot
andauthored
Spaces\Users\Memberships endpoints (#124)
* Spaces Users and Memberships behind a feature flag * Example usage of Spaces\Users\Memberships * PubNub SDK v6.4.0 release. Co-authored-by: Client Engineering Bot <60980775+Client Engineering [email protected]>
1 parent d8cc087 commit 2941205

34 files changed

+1698
-11
lines changed

.pubnub.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: python
2-
version: 6.3.3
2+
version: 6.4.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-6.3.3
21+
package-name: pubnub-6.4.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-6.3.3
101-
location: https://github.com/pubnub/python/releases/download/v6.3.3/pubnub-6.3.3.tar.gz
100+
package-name: pubnub-6.4.0
101+
location: https://github.com/pubnub/python/releases/download/v6.4.0/pubnub-6.4.0.tar.gz
102102
supported-platforms:
103103
supported-operating-systems:
104104
Linux:
@@ -169,6 +169,11 @@ sdks:
169169
license-url: https://github.com/aio-libs/aiohttp/blob/master/LICENSE.txt
170170
is-required: Required
171171
changelog:
172+
- date: 2022-07-13
173+
version: v6.4.0
174+
changes:
175+
- type: feature
176+
text: "Spaces Users and Membership endpoint implementation. This functionality is hidden behind a feature flag. By default it is disabled. To enable it there should be an environment variable named `PN_ENABLE_ENTITIES` set to `True`."
172177
- date: 2022-06-25
173178
version: v6.3.3
174179
changes:

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## v6.4.0
2+
July 13 2022
3+
4+
#### Added
5+
- Spaces Users and Membership endpoint implementation. This functionality is hidden behind a feature flag. By default it is disabled. To enable it there should be an environment variable named `PN_ENABLE_ENTITIES` set to `True`.
6+
17
## v6.3.3
28
June 25 2022
39

examples/entities.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import os
2+
3+
from pubnub.models.consumer.entities.space import Space
4+
from pubnub.models.consumer.entities.user import User
5+
from pubnub.pnconfiguration import PNConfiguration
6+
from pubnub.pubnub import PubNub
7+
8+
pnconfig = PNConfiguration()
9+
10+
pnconfig.subscribe_key = os.getenv('SUB_KEY')
11+
pnconfig.publish_key = os.getenv('PUB_KEY')
12+
pnconfig.secret_key = os.getenv('SEC_KEY')
13+
pnconfig.user_id = "my_uuid"
14+
15+
pnconfig.non_subscribe_request_timeout = 60
16+
pnconfig.connect_timeout = 14
17+
pnconfig.reconnect_policy
18+
print(pnconfig.subscribe_key)
19+
20+
pubnub = PubNub(pnconfig)
21+
22+
space_id = 'blah'
23+
user_id = 'jason-id'
24+
25+
create_space = pubnub.create_space(
26+
space_id=space_id,
27+
name=f'Space ID {space_id}',
28+
description=f'This space ID is {space_id} and is made for demo purpose only',
29+
custom={"created_by": "me"},
30+
space_status='Primary',
31+
space_type='COM',
32+
sync=True
33+
)
34+
35+
print(f"create space result:{create_space.result.__dict__}")
36+
37+
update_space = pubnub.update_space(
38+
space_id=space_id,
39+
name=f'EDIT Space ID {space_id}',
40+
description=f'EDIT: This space ID is {space_id} and is made for demo purpose only',
41+
custom={"created_by": "EDIT me"},
42+
sync=True
43+
)
44+
print(f"update space result: {update_space.result.__dict__}")
45+
46+
fetch_space = pubnub.fetch_space(space_id=space_id, include_custom=True, sync=True)
47+
print(f"fetch space result: {fetch_space.result.__dict__}")
48+
49+
space_id2 = space_id + '2'
50+
create_space = pubnub.create_space(space_id2) \
51+
.set_name(f'Space ID {space_id}') \
52+
.description(f'This space ID is {space_id} and is made for demo purpose only') \
53+
.custom({
54+
"created_by": "me"
55+
}) \
56+
.sync()
57+
58+
all_spaces = pubnub.fetch_spaces(include_custom=True, include_total_count=True).sync()
59+
60+
print(f"fetch spaces result: {all_spaces.result.__dict__}")
61+
62+
rm_space = pubnub.remove_space(space_id2).sync()
63+
print(f"remove space result: {rm_space.result.__dict__}")
64+
65+
user = pubnub.create_user(user_id=user_id, name='Jason', email='[email protected]', sync=True)
66+
67+
users = pubnub.fetch_user(user_id=user_id, sync=True)
68+
print(f"fetch_user: {users.result.__dict__}")
69+
70+
membership = pubnub.add_memberships(user_id=user_id, spaces=Space(space_id=space_id, custom={"a": "b"}), sync=True)
71+
print(f"add_memberships (user_id): {membership.result.__dict__}")
72+
73+
memberships = pubnub.fetch_memberships(user_id=user_id, include_custom=True, sync=True)
74+
print(f"fetch_memberships (user_id): {memberships.result.__dict__}")
75+
76+
print("-------")
77+
78+
membership = pubnub.update_memberships(user_id=user_id, spaces=Space(space_id=space_id, custom={"c": "d"}), sync=True)
79+
print(f"add_memberships (user_id): {membership.result.__dict__}")
80+
81+
memberships = pubnub.fetch_memberships(user_id=user_id, include_custom=True, sync=True)
82+
print(f"fetch_memberships (user_id): {memberships.result.__dict__}")
83+
84+
print("-------")
85+
86+
membership = pubnub.add_memberships(
87+
user_id=user_id, spaces=[Space(space_id='some_2nd_space_id'), Space(space_id='some_3rd_space_id')], sync=True
88+
)
89+
print(f"add_memberships (user_id): {membership.result.__dict__}")
90+
91+
memberships = pubnub.fetch_memberships(user_id=user_id, include_custom=True, sync=True)
92+
print(f"fetch_memberships (user_id): {memberships.result.__dict__}")
93+
94+
print("-------")
95+
96+
membership = pubnub.remove_memberships(user_id=user_id, spaces=Space(space_id=space_id), sync=True)
97+
print(f"remove_memberships (user_id): {membership.result.__dict__}")
98+
99+
memberships = pubnub.fetch_memberships(user_id=user_id, include_custom=True, sync=True)
100+
print(f"fetch_memberships (user_id): {memberships.result.__dict__}")
101+
102+
print("-------")
103+
104+
membership = pubnub.add_memberships(space_id=space_id, users=[User(user_id=user_id, custom={"1": "2"})], sync=True)
105+
print(f"add_memberships (space_id): {membership.result.__dict__}")
106+
107+
memberships = pubnub.fetch_memberships(space_id=space_id, include_custom=True, sync=True)
108+
print(f"fetch_memberships (space_id): {memberships.result.__dict__}")
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
import logging
2+
from abc import ABCMeta
3+
4+
from pubnub import utils
5+
from pubnub.endpoints.endpoint import Endpoint
6+
from pubnub.errors import PNERR_SPACE_MISSING, PNERR_USER_ID_MISSING
7+
from pubnub.exceptions import PubNubException
8+
from pubnub.models.consumer.entities.page import Next, Previous
9+
10+
logger = logging.getLogger("pubnub")
11+
12+
13+
class EntitiesEndpoint(Endpoint):
14+
__metaclass__ = ABCMeta
15+
16+
def __init__(self, pubnub):
17+
Endpoint.__init__(self, pubnub)
18+
19+
def is_auth_required(self):
20+
return True
21+
22+
def connect_timeout(self):
23+
return self.pubnub.config.connect_timeout
24+
25+
def request_timeout(self):
26+
return self.pubnub.config.non_subscribe_request_timeout
27+
28+
def validate_params(self):
29+
self.validate_subscribe_key()
30+
self.validate_specific_params()
31+
32+
def validate_specific_params(self):
33+
pass
34+
35+
def encoded_params(self):
36+
params = {}
37+
if isinstance(self, ListEndpoint):
38+
if self._filter:
39+
params["filter"] = utils.url_encode(str(self._filter))
40+
return params
41+
42+
def custom_params(self):
43+
params = {}
44+
inclusions = []
45+
46+
if isinstance(self, IncludeCustomEndpoint):
47+
if self._include_custom:
48+
inclusions.append("custom")
49+
50+
if isinstance(self, UserIDIncludeEndpoint):
51+
if self._uuid_details_level:
52+
if self._uuid_details_level == UserIDIncludeEndpoint.USER_ID:
53+
inclusions.append("user_id")
54+
elif self._uuid_details_level == UserIDIncludeEndpoint.USER_ID_WITH_CUSTOM:
55+
inclusions.append("user_id.custom")
56+
57+
if isinstance(self, SpaceIDIncludeEndpoint):
58+
if self._space_details_level:
59+
if self._space_details_level == SpaceIDIncludeEndpoint.CHANNEL:
60+
inclusions.append("space")
61+
elif self._space_details_level == SpaceIDIncludeEndpoint.CHANNEL_WITH_CUSTOM:
62+
inclusions.append("space.custom")
63+
64+
if isinstance(self, ListEndpoint):
65+
if self._filter:
66+
params["filter"] = str(self._filter)
67+
68+
if self._limit:
69+
params["limit"] = int(self._limit)
70+
71+
if self._include_total_count:
72+
params["count"] = bool(self._include_total_count)
73+
74+
if self._sort_keys:
75+
joined_sort_params_array = []
76+
for sort_key in self._sort_keys:
77+
joined_sort_params_array.append("%s:%s" % (sort_key.key_str(), sort_key.dir_str()))
78+
79+
params["sort"] = ",".join(joined_sort_params_array)
80+
81+
if self._page:
82+
if isinstance(self._page, Next):
83+
params["start"] = self._page.hash
84+
elif isinstance(self._page, Previous):
85+
params["end"] = self._page.hash
86+
else:
87+
raise ValueError()
88+
89+
if len(inclusions) > 0:
90+
params["include"] = ",".join(inclusions)
91+
92+
return params
93+
94+
95+
class CustomAwareEndpoint:
96+
__metaclass__ = ABCMeta
97+
98+
def __init__(self):
99+
self._custom = None
100+
101+
def custom(self, custom):
102+
self._custom = dict(custom)
103+
return self
104+
105+
106+
class SpaceEndpoint:
107+
__metaclass__ = ABCMeta
108+
109+
def __init__(self):
110+
self._space_id = None
111+
112+
def space_id(self, space):
113+
self._space_id = str(space)
114+
return self
115+
116+
def _validate_space_id(self):
117+
if self._space_id is None or len(self._space_id) == 0:
118+
raise PubNubException(pn_error=PNERR_SPACE_MISSING)
119+
120+
121+
class UserEndpoint:
122+
__metaclass__ = ABCMeta
123+
124+
def __init__(self):
125+
self._user_id = None
126+
127+
def user_id(self, user_id):
128+
self._user_id = str(user_id)
129+
return self
130+
131+
def _effective_user_id(self):
132+
if self._user_id is not None:
133+
return self._user_id
134+
else:
135+
return self.pubnub.config.user_id
136+
137+
def _validate_user_id(self):
138+
if self._effective_user_id() is None or len(self._effective_user_id()) == 0:
139+
raise PubNubException(pn_error=PNERR_USER_ID_MISSING)
140+
141+
142+
class UsersEndpoint:
143+
__metaclass__ = ABCMeta
144+
145+
def __init__(self):
146+
self._users = None
147+
148+
def users(self, users):
149+
self._users = users
150+
return self
151+
152+
153+
class SpacesEndpoint:
154+
__metaclass__ = ABCMeta
155+
156+
def __init__(self):
157+
self._spaces = None
158+
159+
def spaces(self, spaces):
160+
self._spaces = spaces
161+
return self
162+
163+
164+
class ListEndpoint:
165+
__metaclass__ = ABCMeta
166+
167+
def __init__(self):
168+
self._limit = None
169+
self._filter = None
170+
self._include_total_count = None
171+
self._sort_keys = None
172+
self._page = None
173+
174+
def limit(self, limit):
175+
self._limit = int(limit)
176+
return self
177+
178+
def filter(self, filter):
179+
self._filter = str(filter)
180+
return self
181+
182+
def include_total_count(self, include_total_count):
183+
self._include_total_count = bool(include_total_count)
184+
return self
185+
186+
def sort(self, *sort_keys):
187+
self._sort_keys = sort_keys
188+
return self
189+
190+
def page(self, page):
191+
self._page = page
192+
return self
193+
194+
195+
class IncludeCustomEndpoint:
196+
__metaclass__ = ABCMeta
197+
198+
def __init__(self):
199+
self._include_custom = None
200+
201+
def include_custom(self, include_custom):
202+
self._include_custom = bool(include_custom)
203+
return self
204+
205+
206+
class UserIDIncludeEndpoint:
207+
__metaclass__ = ABCMeta
208+
209+
USER_ID = 1
210+
USER_ID_WITH_CUSTOM = 2
211+
212+
def __init__(self):
213+
self._user_id_details_level = None
214+
215+
def include_user_id(self, user_id_details_level):
216+
self._user_id_details_level = user_id_details_level
217+
return self
218+
219+
220+
class SpaceIDIncludeEndpoint:
221+
__metaclass__ = ABCMeta
222+
223+
SPACE = 1
224+
SPACE_WITH_CUSTOM = 2
225+
226+
def __init__(self):
227+
self._space_details_level = None
228+
229+
def include_space(self, space_details_level):
230+
self._space_details_level = space_details_level
231+
return self

0 commit comments

Comments
 (0)