Skip to content

Commit ab3cc59

Browse files
authored
Adding Pages API (#6)
Adding Pages API and examples
1 parent a641cab commit ab3cc59

File tree

6 files changed

+362
-4
lines changed

6 files changed

+362
-4
lines changed

examples/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .dataset import datasets
22
from .group import groups
3-
#from .page import pages
3+
from .page import pages
44
from .stream import streams
55
from .user import users

examples/page.py

+56-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,56 @@
1-
TO DO
1+
2+
3+
def pages(domo):
4+
'''Page Docs: https://developer.domo.com/docs/domo-apis/pages
5+
'''
6+
domo.logger.info("\n**** Domo API - Page Examples ****\n")
7+
8+
# Create a page
9+
page = domo.pages.create('New Page')
10+
domo.logger.info("Created Page {}".format(page['id']))
11+
12+
# Create a subpage
13+
subpage = domo.pages.create('Sub Page', parentId=page['id'])
14+
domo.logger.info("Created Subpage {}".format(subpage['id']))
15+
16+
# Update the page using returned page
17+
page['name'] = 'Updated Page'
18+
domo.pages.update(**page)
19+
domo.logger.info("Renamed Page {}".format(page['id']))
20+
21+
# Turn subpage into to top-level page using keyword argument
22+
domo.pages.update(subpage['id'], parentId=None)
23+
domo.logger.info("Moved Page to top level {}".format(subpage['id']))
24+
25+
# Get the page
26+
page = domo.pages.get(page['id'])
27+
28+
# List pages
29+
page_list = list(domo.pages.list())
30+
domo.logger.info("Retrieved a list of {} top-level page(s)".format(
31+
len(page_list)))
32+
33+
# Create a few collections
34+
collections = [
35+
domo.pages.create_collection(page['id'], 'First Collection'),
36+
domo.pages.create_collection(page['id'], 'Second Collection'),
37+
]
38+
domo.logger.info("Created two collections on page {}".format(page['id']))
39+
40+
# Get collections
41+
collection_list = domo.pages.get_collections(page['id'])
42+
domo.logger.info("Retrieved a list of {} collections".format(
43+
len(collection_list)))
44+
45+
# Update collection
46+
collections[1]['title'] = 'Last Collection'
47+
domo.pages.update_collection(page['id'], **collections[1])
48+
domo.logger.info("Updated collection {}: {}".format(collections[1]['id'],
49+
collections[1]['title']))
50+
51+
# Clean up
52+
for collection in collections:
53+
domo.pages.delete_collection(page['id'], collection['id'])
54+
domo.pages.delete(page['id'])
55+
domo.pages.delete(subpage['id'])
56+
domo.logger.info("Deleted collections and pages")

pydomo/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from pydomo.Transport import DomoAPITransport
22
from pydomo.datasets import DataSetClient
33
from pydomo.groups import GroupClient
4+
from pydomo.pages import PageClient
45
from pydomo.streams import StreamClient
56
from pydomo.users import UserClient
67
import logging
@@ -73,7 +74,8 @@ def __init__(self, client_id, client_secret, api_host='api.domo.com', **kwargs):
7374
self.logger.debug("\n" + DOMO + "\n")
7475

7576
self.transport = DomoAPITransport(client_id, client_secret, api_host, kwargs.get('use_https', True), self.logger)
76-
self.streams = StreamClient(self.transport, self.logger)
7777
self.datasets = DataSetClient(self.transport, self.logger)
7878
self.groups = GroupClient(self.transport, self.logger)
79+
self.pages = PageClient(self.transport, self.logger)
80+
self.streams = StreamClient(self.transport, self.logger)
7981
self.users = UserClient(self.transport, self.logger)

pydomo/pages/PageClient.py

+300
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
import requests
2+
3+
from pydomo.DomoAPIClient import DomoAPIClient
4+
from pydomo.Transport import HTTPMethod
5+
6+
PAGE_DESC = "Page"
7+
COLLECTION_DESC = "Collection"
8+
URL_BASE = '/v1/pages'
9+
10+
PAGE_CREATION_KWARGS = [
11+
'parentId',
12+
'locked',
13+
'cardIds',
14+
'visibility'
15+
]
16+
17+
PAGE_UPDATE_KWARGS = [
18+
'id',
19+
'name',
20+
'parentId',
21+
'ownerId',
22+
'locked',
23+
'collectionIds',
24+
'cardIds',
25+
'visibility'
26+
]
27+
28+
COLLECTION_CREATION_KWARGS = [
29+
'description',
30+
'cardIds'
31+
]
32+
33+
COLLECTION_UPDATE_KWARGS = [
34+
'id',
35+
'description',
36+
'cardIds',
37+
'title'
38+
]
39+
40+
41+
class PageClient(DomoAPIClient):
42+
"""
43+
Pages
44+
- Programmatically manage Domo Pages
45+
- Docs: https://developer.domo.com/docs/data-apis/pages
46+
"""
47+
48+
def create(self, name, **kwargs):
49+
"""Create a new page.
50+
51+
>>> page = {'name':'New Page'}
52+
>>> new_page = domo.pages.create(**page)
53+
>>> print(new_page)
54+
{'id': 123456789, 'parentId': 0, 'name': 'My Page',
55+
'locked': False, 'ownerId': 12345, 'cardIds': [],
56+
'visibility': {'userIds': 12345}}
57+
58+
:Parameters:
59+
- `name`: The name of the new page
60+
- `parentId`: (optional) If present create page as subpage
61+
- `locked`: (optional) whether to lock the page
62+
- `cardIds`: (optional) cards to place on the page
63+
- `visibility`: (optional) dict of userIds and/or groupIds to
64+
give access to
65+
66+
:Returns:
67+
- A dict representing the page
68+
"""
69+
70+
self._validate_params(kwargs, PAGE_CREATION_KWARGS)
71+
72+
page_request = {'name': name}
73+
page_request.update(kwargs)
74+
return self._create(URL_BASE, page_request, {}, PAGE_DESC)
75+
76+
def get(self, page_id):
77+
"""Get a page.
78+
79+
>>> page = domo.pages.get(page_id)
80+
>>> print(page)
81+
{'id': 123456789, 'parentId': 0, 'name': 'My Page',
82+
'locked': False, 'ownerId': 12345, 'cardIds': [],
83+
'visibility': {'userIds': 12345}}
84+
85+
:Parameters:
86+
- `page_id`: ID of the page to get
87+
88+
:returns:
89+
- A dict representing the page
90+
"""
91+
url = '{base}/{page_id}'.format(base=URL_BASE, page_id=page_id)
92+
return self._get(url, PAGE_DESC)
93+
94+
def list(self, per_page=50, offset=0, limit=0):
95+
"""List pages.
96+
Returns a generator that will call the API multiple times
97+
If limit is supplied and non-zero, returns up to limit pages
98+
99+
>>> list(domo.pages.list())
100+
[{'id': 123456789, 'name': 'My Page', 'children': []}, ...]
101+
102+
:returns:
103+
- A list of dicts (with nesting possible)
104+
"""
105+
# API uses pagination with a max of 50 per page
106+
if per_page not in range(1, 51):
107+
raise ValueError('per_page must be between 1 and 50 (inclusive)')
108+
# Don't pull 50 values if user requests 10
109+
if limit:
110+
per_page = min(per_page, limit)
111+
112+
params = {
113+
'limit': per_page,
114+
'offset': offset,
115+
}
116+
page_count = 0
117+
118+
pages = self._list(URL_BASE, params, PAGE_DESC)
119+
while pages:
120+
for page in pages:
121+
yield page
122+
page_count += 1
123+
if limit and page_count >= limit:
124+
return
125+
126+
params['offset'] += per_page
127+
if limit and params['offset'] + per_page > limit:
128+
# Don't need to pull more than the limit
129+
params['limit'] = limit - params['offset']
130+
pages = self._list(URL_BASE, params, PAGE_DESC)
131+
132+
def update(self, page_id=None, **kwargs):
133+
"""Update a page.
134+
135+
>>> print(domo.pages.get(page_id))
136+
{'id': 123456789, 'parentId': 0, 'name': 'My Page',
137+
'locked': False, 'ownerId': 12345, 'cardIds': [],
138+
'visibility': {'userIds': 12345}}
139+
>>> domo.pages.update(page_id, locked=True,
140+
cardIds=[54321, 13579])
141+
>>> print(domo.pages.get(page_id))
142+
{'id': 123456789, 'parentId': 0, 'name': 'My Page',
143+
'locked': True, 'ownerId': 12345, 'cardIds': [54321, 13579],
144+
'visibility': {'userIds': 12345}}
145+
146+
# Using **kwargs:
147+
>>> page = domo.pages.get(page_id)
148+
>>> page['cardIds'].append(new_card_id)
149+
>>> domo.pages.update(**page)
150+
151+
:Parameters:
152+
- `page_id`: ID of the page to update. Can also be provided
153+
by supplying `id` to **kwargs. This allows for calling get,
154+
updating the returned object, then passing it to update.
155+
- `name`: (optional) rename the page
156+
- `parentId`: (optional) turn page into subpage, or subpage
157+
into top-level page if parentId is present and falsey
158+
- `ownerId`: (optional) change owner of the page
159+
- `locked`: (optional) lock or unlock the page
160+
- `collectionIds`: (optional) reorder collections on page
161+
- `cardIds`: (optional) specify which cards to have on page
162+
- `visibility`: (optional) change who can see the page
163+
"""
164+
165+
self._validate_params(kwargs, PAGE_UPDATE_KWARGS)
166+
if page_id is None and 'id' not in kwargs:
167+
raise TypeError("update() missing required argument: 'page_id'")
168+
elif 'id' in kwargs:
169+
if page_id is not None and page_id != kwargs['id']:
170+
raise ValueError('ambiguous page ID - page_id and id both '
171+
'supplied but do not match')
172+
page_id = kwargs['id']
173+
del kwargs['id']
174+
if not kwargs.get('parentId', True):
175+
# Check if parentId is present and falsey
176+
kwargs['parentId'] = 0
177+
178+
url = '{base}/{page_id}'.format(base=URL_BASE, page_id=page_id)
179+
return self._update(url,
180+
HTTPMethod.PUT,
181+
requests.codes.NO_CONTENT,
182+
kwargs,
183+
PAGE_DESC)
184+
185+
def delete(self, page_id):
186+
"""Delete a page.
187+
188+
:Parameters:
189+
- `page_id`: ID of the page to delete
190+
"""
191+
url = '{base}/{page_id}'.format(base=URL_BASE, page_id=page_id)
192+
return self._delete(url, PAGE_DESC)
193+
194+
def create_collection(self, page_id, title, **kwargs):
195+
"""Create a collection on a page.
196+
197+
>>> collection = domo.pages.create_collection(page_id,
198+
'Collection')
199+
>>> print(collection)
200+
{'id': 1234321, 'title': 'Collection', 'description': '',
201+
'cardIds': []}
202+
203+
:Parameters:
204+
- `page_id`: ID of the page to create a collection on
205+
- `title`: The title of the collection
206+
- `description`: (optional) The description of the collection
207+
- `cardIds`: (optional) cards to place in the collection
208+
209+
:Returns:
210+
- A dict representing the collection
211+
"""
212+
213+
self._validate_params(kwargs, COLLECTION_CREATION_KWARGS)
214+
collection_request = {'title': title}
215+
collection_request.update(kwargs)
216+
217+
url = '{base}/{page_id}/collections'.format(
218+
base=URL_BASE, page_id=page_id)
219+
return self._create(url, collection_request, {}, COLLECTION_DESC)
220+
221+
def get_collections(self, page_id):
222+
"""Get a collections of a page
223+
224+
>>> print(domo.pages.get_collections(page_id))
225+
[{'id': 1234321, 'title': 'Collection', 'description': '',
226+
'cardIds': []}]
227+
228+
:Parameters:
229+
- `page_id`: ID of the page
230+
231+
:Returns:
232+
- A list of dicts representing the collections
233+
"""
234+
url = '{base}/{page_id}/collections'.format(base=URL_BASE,
235+
page_id=page_id)
236+
return self._get(url, COLLECTION_DESC)
237+
238+
def update_collection(self, page_id, collection_id=None, **kwargs):
239+
"""Update a collection of a page.
240+
241+
>>> collections = domo.pages.get_collections(page_id)
242+
>>> print(collections)
243+
[{'id': 1234321, 'title': 'Collection', 'description': '',
244+
'cardIds': []}]
245+
>>> collection_id = collections[0]['id']
246+
>>> domo.pages.update_collection(page_id, collection_id,
247+
description='description',
248+
cardIds=[54321, 13579])
249+
>>> print(domo.pages.get_collections(page_id))
250+
[{'id': 1234321, 'title': 'Collection',
251+
'description': 'description', 'cardIds': [54321, 13579]}]
252+
253+
# Using **kwargs:
254+
>>> collections = domo.pages.get_collections(page_id)
255+
>>> collections[0]['description'] = 'Description'
256+
>>> domo.pages.update_collection(page_id, **collections[0])
257+
258+
:Parameters:
259+
- `page_id`: ID of the page the collection is on
260+
- `collection_id`: ID of the collection. Can also be provided
261+
by supplying `id` to **kwargs. This allows for calling
262+
get_collections, updating one of the returned collections,
263+
then passing it to update_collection.
264+
- `title`: (optional) update the title
265+
- `description`: (optional) update the description
266+
- `cardIds`: (optional) update cards in the collection
267+
268+
:Returns:
269+
- A dict representing the collection
270+
"""
271+
272+
self._validate_params(kwargs, COLLECTION_UPDATE_KWARGS)
273+
if collection_id is None and 'id' not in kwargs:
274+
raise TypeError("update() missing required argument: "
275+
"'collection_id'")
276+
elif 'id' in kwargs:
277+
if collection_id is not None and collection_id != kwargs['id']:
278+
raise ValueError('ambiguous collection ID - collection_id and'
279+
' id both supplied but do not match')
280+
collection_id = kwargs['id']
281+
del kwargs['id']
282+
283+
url = '{base}/{page_id}/collections/{collection_id}'.format(
284+
base=URL_BASE, page_id=page_id, collection_id=collection_id)
285+
return self._update(url,
286+
HTTPMethod.PUT,
287+
requests.codes.NO_CONTENT,
288+
kwargs,
289+
COLLECTION_DESC)
290+
291+
def delete_collection(self, page_id, collection_id):
292+
"""Delete a collection from a page.
293+
294+
:Parameters:
295+
- `page_id`: ID of the page the collection is on
296+
- `collection_id`: ID of the collection to delete
297+
"""
298+
url = '{base}/{page_id}/collections/{collection_id}'.format(
299+
base=URL_BASE, page_id=page_id, collection_id=collection_id)
300+
return self._delete(url, COLLECTION_DESC)

pydomo/pages/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .PageClient import PageClient

run_examples.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,6 @@ def init_domo_client(client_id, client_secret, **kwargs):
4848
domo = init_domo_client(CLIENT_ID, CLIENT_SECRET, api_host=API_HOST)
4949
examples.datasets(domo)
5050
examples.groups(domo)
51-
#examples.pages(domo)
51+
examples.pages(domo)
5252
examples.streams(domo)
5353
examples.users(domo)

0 commit comments

Comments
 (0)