Skip to content

Commit b8359fc

Browse files
authored
feat: add objects, move preferences, add bulk apis (#5)
* feat: add objects, move preferences, add bulk apis * feat: add bulk_set_preferences method * fix: update readme * fix: bulk delete
1 parent 4cebdca commit b8359fc

File tree

8 files changed

+436
-172
lines changed

8 files changed

+436
-172
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ client.notify(
6868
)
6969

7070
```
71+
7172
### Getting and setting channel data
7273

7374
```python
@@ -107,14 +108,14 @@ from knockapi import Knock
107108
client = Knock(api_key="sk_12345")
108109

109110
# Replaces the preferences for the user
110-
client.preferences.update(
111+
client.users.set_preferences(
111112
user_id="jhammond",
112113
channel_types={'email': True},
113114
workflows={'dinosaurs-loose': False}
114115
)
115116

116117
# Retrieve the current preferences
117-
client.preferences.get(user_id="jhammond")
118+
client.users.get_preferences(user_id="jhammond")
118119
```
119120

120121
### Signing JWTs

knockapi/client.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ def preferences(self):
5353
from .resources import Preferences
5454
return Preferences(self)
5555

56+
@property
57+
def objects(self):
58+
from .resources import Objects
59+
return Objects(self)
60+
61+
@property
62+
def bulk_operations(self):
63+
from .resources import BulkOperations
64+
return BulkOperations(self)
65+
66+
# Defined at the top level here for convienience
5667
def notify(self, key, actor, recipients, data={}, cancellation_key=None, tenant=None):
5768
"""
5869
Triggers a workflow.

knockapi/resources/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
from .users import User
22
from .workflows import Workflows
33
from .preferences import Preferences
4+
from .objects import Objects
5+
from .bulk_operations import BulkOperations

knockapi/resources/bulk_operations.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from .service import Service
2+
3+
default_set_id = "default"
4+
5+
6+
class BulkOperations(Service):
7+
def get(self, id):
8+
"""
9+
Returns an bulk operation.
10+
11+
Args:
12+
id (str): The id of the bulk operation
13+
14+
Returns:
15+
dict: A Knock BulkOperation
16+
"""
17+
endpoint = '/bulk_operations/{}'.format(id)
18+
return self.client.request('get', endpoint)

knockapi/resources/objects.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from .service import Service
2+
3+
default_set_id = "default"
4+
5+
6+
class Objects(Service):
7+
def get(self, collection, id):
8+
"""
9+
Returns an object in a collection with the id given.
10+
11+
Args:
12+
collection (str): The collection the object belongs to
13+
id (str): The id of the object in the collection
14+
15+
Returns:
16+
dict: A Knock Object
17+
"""
18+
endpoint = '/objects/{}/{}'.format(collection, id)
19+
return self.client.request('get', endpoint)
20+
21+
# NOTE: This is `set_object` as `set` is a reserved keyword
22+
def set_object(self, collection, id, data = {}):
23+
"""
24+
Returns an object in a collection with the id given.
25+
26+
Args:
27+
collection (str): The collection the object belongs to
28+
id (str): The id of the object in the collection
29+
data (dict): The data to set on the object
30+
31+
Returns:
32+
dict: A Knock Object
33+
"""
34+
endpoint = '/objects/{}/{}'.format(collection, id)
35+
return self.client.request('put', endpoint, payload = data)
36+
37+
def bulk_set(self, collection, objects):
38+
"""
39+
Bulk sets up to 100 objects in a collection.
40+
41+
Args:
42+
collection (str): The collection the object belongs to
43+
objects (array): The list of object dictionaries to set
44+
45+
Returns:
46+
dict: BulkOperation from Knock
47+
"""
48+
data = { 'objects': objects }
49+
endpoint = '/objects/{}/bulk/set'.format(collection)
50+
return self.client.request('post', endpoint, payload=data)
51+
52+
def delete(self, collection, id):
53+
"""
54+
Deletes the given object.
55+
56+
Args:
57+
collection (str): The collection the object belongs to
58+
id (str): The id of the object in the collection
59+
60+
Returns:
61+
None: No response
62+
"""
63+
endpoint = '/objects/{}/{}'.format(collection, id)
64+
return self.client.request('delete', endpoint)
65+
66+
def bulk_delete(self, collection, object_ids):
67+
"""
68+
Bulk deletes up to 100 objects in a collection.
69+
70+
Args:
71+
collection (str): The collection the object belongs to
72+
object_ids (array): The list of object ids to delete
73+
74+
Returns:
75+
dict: BulkOperation from Knock
76+
"""
77+
data = { 'object_ids': object_ids }
78+
endpoint = '/objects/{}/bulk/delete'.format(collection)
79+
return self.client.request('post', endpoint, payload=data)
80+
81+
##
82+
# Channel data
83+
##
84+
85+
def get_channel_data(self, collection, id, channel_id):
86+
"""
87+
Get user's channel data for the given channel id.
88+
89+
Args:
90+
collection (str): The collection the object belongs to
91+
id (str): The id of the object in the collection
92+
channel_id (str): Target channel ID
93+
94+
Returns:
95+
dict: Channel data from Knock.
96+
"""
97+
endpoint = '/objects/{}/{}/channel_data/{}'.format(collection, id, channel_id)
98+
return self.client.request('get', endpoint)
99+
100+
def set_channel_data(self, collection, id, channel_id, channel_data):
101+
"""
102+
Upserts user's channel data for the given channel id.
103+
104+
Args:
105+
collection (str): The collection the object belongs to
106+
id (str): The id of the object in the collection
107+
channel_id (str): Target channel ID
108+
channel_data (dict): Channel data
109+
110+
Returns:
111+
dict: Channel data from Knock.
112+
"""
113+
endpoint = '/objects/{}/{}/channel_data/{}'.format(collection, id, channel_id)
114+
return self.client.request('put', endpoint, payload={'data': channel_data})

knockapi/resources/preferences.py

Lines changed: 20 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -1,184 +1,39 @@
11
from .service import Service
2-
3-
default_set_id = "default"
4-
2+
from warnings import warn
53

64
class Preferences(Service):
75
def get_all(self, user_id):
8-
"""
9-
Get a users full set of preferences
10-
11-
Args:
12-
user_id: The users ID
13-
14-
Returns:
15-
dict: User response from Knock.
16-
"""
17-
endpoint = '/users/{}/preferences'.format(user_id)
18-
return self.client.request('get', endpoint)
6+
warn("This method is deprecated. Use users.get_all_preferences instead.", DeprecationWarning, stacklevel=2)
7+
return self.client.users.get_all_preferences(user_id)
198

209
def get(self, user_id, options={}):
21-
"""
22-
Get a users preference set
23-
24-
Args:
25-
user_id (str): The users ID
26-
options (dict):
27-
preference_set (str): The preference set to retrieve (defaults to "default")
28-
29-
Returns:
30-
dict: User response from Knock.
31-
"""
32-
preference_set_id = options.get('preference_set', default_set_id)
33-
endpoint = '/users/{}/preferences/{}'.format(
34-
user_id, preference_set_id)
35-
36-
return self.client.request('get', endpoint)
10+
warn("This method is deprecated. Use users.get_preferences instead.", DeprecationWarning, stacklevel=2)
11+
return self.client.users.get_preferences(user_id, options)
3712

3813
def update(self, user_id, channel_types=None, categories=None, workflows=None, options={}):
39-
"""
40-
Sets the preference set for the user
41-
42-
Args:
43-
user_id (str): The users ID
44-
channel_types (dict): A dictionary of channel type preferences
45-
categories (dict): A dictionary of category preferences
46-
workflows (dict): A dictionary of workflow preferences
47-
options (dict): A dictionary of options
48-
49-
Returns:
50-
dict: User response from Knock.
51-
"""
52-
preference_set_id = options.get('preference_set', default_set_id)
53-
54-
endpoint = '/users/{}/preferences/{}'.format(
55-
user_id, preference_set_id)
56-
57-
params = {
58-
'channel_types': channel_types,
59-
'categories': categories,
60-
'workflows': workflows
61-
}
62-
63-
return self.client.request('put', endpoint, payload=params)
14+
warn("This method is deprecated. Use users.set_preferences instead.", DeprecationWarning, stacklevel=2)
15+
return self.client.users.set_preferences(user_id, channel_types=channel_types, categories=categories, workflows=workflows, options=options)
6416

6517
def set_channel_types(self, user_id, preferences, options={}):
66-
"""
67-
Sets the channel type preferences for the user
68-
69-
Args:
70-
user_id (str): The users ID
71-
preferences (dict): A dictionary of channel type preferences
72-
options (dict): A dictionary of options
73-
74-
Returns:
75-
dict: User response from Knock.
76-
"""
77-
preference_set_id = options.get('preference_set', default_set_id)
78-
79-
endpoint = '/users/{}/preferences/{}/channel_types'.format(
80-
user_id, preference_set_id)
81-
82-
return self.client.request('put', endpoint, payload=preferences)
18+
warn("This method is deprecated. Use users.set_channel_types_preferences instead.", DeprecationWarning, stacklevel=2)
19+
return self.client.users.set_channel_types_preferences(user_id, preferences, options=options)
8320

8421
def set_channel_type(self, user_id, channel_type, setting, options={}):
85-
"""
86-
Sets the channel type preference for the user
87-
88-
Args:
89-
user_id (str): The users ID
90-
channel_type (str): The channel_type to set
91-
setting (boolean): The preference setting
92-
options (dict): A dictionary of options
93-
94-
Returns:
95-
dict: User response from Knock.
96-
"""
97-
preference_set_id = options.get('preference_set', default_set_id)
98-
99-
endpoint = '/users/{}/preferences/{}/channel_types/{}'.format(
100-
user_id, preference_set_id, channel_type)
101-
102-
return self.client.request('put', endpoint, payload={'subscribed': setting})
22+
warn("This method is deprecated. Use users.set_channel_type_preferences instead.", DeprecationWarning, stacklevel=2)
23+
return self.client.users.set_channel_types_preferences(user_id, channel_type, setting, options=options)
10324

10425
def set_workflows(self, user_id, preferences, options={}):
105-
"""
106-
Sets the workflow preferences for the user
107-
108-
Args:
109-
user_id (str): The users ID
110-
preferences (dict): A dictionary of workflow preferences
111-
options (dict): A dictionary of options
112-
113-
Returns:
114-
dict: User response from Knock.
115-
"""
116-
preference_set_id = options.get('preference_set', default_set_id)
117-
118-
endpoint = '/users/{}/preferences/{}/workflows'.format(
119-
user_id, preference_set_id)
120-
121-
return self.client.request('put', endpoint, payload=preferences)
26+
warn("This method is deprecated. Use users.set_workflows_preferences instead.", DeprecationWarning, stacklevel=2)
27+
return self.client.users.set_workflows_preferences(user_id, preferences, options=options)
12228

12329
def set_workflow(self, user_id, key, setting, options={}):
124-
"""
125-
Sets the workflow preferences for the user
126-
127-
Args:
128-
user_id (str): The users ID
129-
key (str): The workflow key
130-
setting (boolean or dict): The preference setting
131-
options (dict): A dictionary of options
132-
133-
Returns:
134-
dict: User response from Knock.
135-
"""
136-
preference_set_id = options.get('preference_set', default_set_id)
137-
138-
endpoint = '/users/{}/preferences/{}/workflows/{}'.format(
139-
user_id, preference_set_id, key)
140-
141-
params = setting if type(setting) is dict else {'subscribed': setting}
142-
143-
return self.client.request('put', endpoint, payload=params)
30+
warn("This method is deprecated. Use users.set_workflow_preferences instead.", DeprecationWarning, stacklevel=2)
31+
return self.client.users.set_workflow_preferences(user_id, key, setting, setting, options=options)
14432

14533
def set_categories(self, user_id, preferences, options={}):
146-
"""
147-
Sets the categories preferences for the user
148-
149-
Args:
150-
user_id (str): The users ID
151-
preferences (dict): A dictionary of category preferences
152-
options (dict): A dictionary of options
153-
154-
Returns:
155-
dict: User response from Knock.
156-
"""
157-
preference_set_id = options.get('preference_set', default_set_id)
158-
159-
endpoint = '/users/{}/preferences/{}/categories'.format(
160-
user_id, preference_set_id)
161-
162-
return self.client.request('put', endpoint, payload=preferences)
163-
34+
warn("This method is deprecated. Use users.set_categories_preferences instead.", DeprecationWarning, stacklevel=2)
35+
return self.client.users.set_categories_preferences(user_id, preferences, options=options)
36+
16437
def set_category(self, user_id, key, setting, options={}):
165-
"""
166-
Sets the category preferences for the user
167-
168-
Args:
169-
user_id (str): The users ID
170-
key (str): The category key
171-
setting (boolean or dict): The preference setting
172-
options (dict): A dictionary of options
173-
174-
Returns:
175-
dict: User response from Knock.
176-
"""
177-
preference_set_id = options.get('preference_set', default_set_id)
178-
179-
endpoint = '/users/{}/preferences/{}/categories/{}'.format(
180-
user_id, preference_set_id, key)
181-
182-
params = setting if type(setting) is dict else {'subscribed': setting}
183-
184-
return self.client.request('put', endpoint, payload=params)
38+
warn("This method is deprecated. Use users.set_category_preferences instead.", DeprecationWarning, stacklevel=2)
39+
return self.client.users.set_category_preferences(user_id, key, setting, setting, options=options)

0 commit comments

Comments
 (0)