Skip to content

Commit 23d2cad

Browse files
committed
Clean up RestSession methods add DEFAULT_API_URL
Break out some code and checks to helper functions and add comments to improve readability. Add a DEFAULT_API_URL module constant so that an API URL doesn’t have to be specified for most use cases.
1 parent f81ac4a commit 23d2cad

File tree

1 file changed

+82
-50
lines changed

1 file changed

+82
-50
lines changed

ciscosparkapi/restsession.py

Lines changed: 82 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
"""RestSession class for creating 'connections' to the Cisco Spark APIs."""
22

3+
34
import urlparse
45
import requests
56
import exception
67

78

8-
GET_EXPECTED_RESPONSE_CODE = 200
9-
POST_EXPECTED_RESPONSE_CODE = 200
10-
PUT_EXPECTED_RESPONSE_CODE = 200
11-
DELETE_EXPECTED_RESPONSE_CODE = 204
9+
# Default api.ciscospark.com base URL
10+
DEFAULT_API_URL = 'https://api.ciscospark.com/v1/'
11+
12+
# Cisco Spark cloud Expected Response Codes (HTTP Response Codes)
13+
ERC = {'GET': 200,
14+
'POST': 200,
15+
'PUT': 200,
16+
'DELETE': 204}
1217

1318

1419
def _validate_base_url(base_url):
@@ -21,8 +26,13 @@ def _validate_base_url(base_url):
2126
raise exception.CiscoSparkApiException(error_message)
2227

2328

24-
def _check_response(response, expected_response_code):
25-
if response.status_code != expected_response_code:
29+
def _raise_if_extra_kwargs(kwargs):
30+
if kwargs:
31+
raise TypeError("Unexpected **kwargs: %r" % kwargs)
32+
33+
34+
def _check_response_code(response, erc):
35+
if response.status_code != erc:
2636
raise exception.CiscoSparkApiError(response.status_code,
2737
request=response.request,
2838
response=response)
@@ -33,7 +43,7 @@ def _extract_and_parse_json(response):
3343

3444

3545
class RestSession(object):
36-
def __init__(self, base_url, access_token, timeout=None):
46+
def __init__(self, access_token, base_url=DEFAULT_API_URL, timeout=None):
3747
super(RestSession, self).__init__()
3848
self._base_url = _validate_base_url(base_url)
3949
self._access_token = access_token
@@ -70,86 +80,108 @@ def timeout(self, value):
7080
def urljoin(self, suffix_url):
7181
return urlparse.urljoin(self.base_url, suffix_url)
7282

73-
def get(self, url, **kwargs):
83+
def get(self, url, params=None, **kwargs):
84+
# Process args
85+
assert isinstance(url, basestring)
86+
assert params is None or isinstance(params, dict)
87+
abs_url = self.urljoin(url)
88+
# Process kwargs
7489
timeout = kwargs.pop('timeout', self.timeout)
75-
expected_response_code = kwargs.pop('expected_response_code',
76-
GET_EXPECTED_RESPONSE_CODE)
77-
if kwargs:
78-
raise TypeError(' Unexpected **kwargs: %r' % kwargs)
90+
erc = kwargs.pop('erc', ERC['GET'])
91+
_raise_if_extra_kwargs(kwargs)
7992
# API request
80-
response = self._req_session.get(self.urljoin(url), timeout=timeout)
93+
response = self._req_session.get(abs_url,
94+
params=params,
95+
timeout=timeout)
8196
# Process response
82-
_check_response(response, expected_response_code)
97+
_check_response_code(response, erc)
8398
return _extract_and_parse_json(response)
8499

85-
def get_pages(self, url, **kwargs):
100+
def get_pages(self, url, params=None, **kwargs):
101+
# Process args
102+
assert isinstance(url, basestring)
103+
assert params is None or isinstance(params, dict)
104+
abs_url = self.urljoin(url)
105+
# Process kwargs
86106
timeout = kwargs.pop('timeout', self.timeout)
87-
expected_response_code = kwargs.pop('expected_response_code',
88-
GET_EXPECTED_RESPONSE_CODE)
89-
if kwargs:
90-
raise TypeError(' Unexpected **kwargs: %r' % kwargs)
107+
erc = kwargs.pop('erc', ERC['GET'])
108+
_raise_if_extra_kwargs(kwargs)
91109
# API request - get first page
92-
response = self._req_session.get(self.urljoin(url), timeout=timeout)
93-
_check_response(response, expected_response_code)
94-
json_dict = _extract_and_parse_json(response)
110+
response = self._req_session.get(abs_url,
111+
params=params,
112+
timeout=timeout)
95113
while True:
96-
# Yield response content
97-
yield json_dict
114+
# Process response - Yield page's JSON data
115+
_check_response_code(response, erc)
116+
yield _extract_and_parse_json(response)
98117
# Get next page
99118
if response.links.get('next'):
100119
next_url = response.links.get('next').get('url')
101120
# API request - get next page
102121
response = self._req_session.get(next_url, timeout=timeout)
103-
_check_response(response, expected_response_code)
104-
json_dict = _extract_and_parse_json(response)
105122
else:
106123
raise StopIteration
107124

108-
def get_items(self, url, **kwargs):
109-
pages = self.get_pages(url, **kwargs)
110-
for json_dict in pages:
111-
assert isinstance(json_dict, dict)
112-
items = json_dict.get(u'items')
125+
def get_items(self, url, params=None, **kwargs):
126+
# Get iterator for pages of JSON data
127+
pages = self.get_pages(url, params=params, **kwargs)
128+
# Process pages
129+
for json_page in pages:
130+
# Process each page of JSON data yielding the individual JSON
131+
# objects contained within the top level 'items' array
132+
assert isinstance(json_page, dict)
133+
items = json_page.get(u'items')
113134
if items:
114135
for item in items:
115136
yield item
116137
else:
117138
error_message = "'items' object not found in JSON data: %r" \
118-
% json_dict
139+
% json_page
119140
raise exception.CiscoSparkApiException(error_message)
120141

121142
def post(self, url, json_dict, **kwargs):
143+
# Process args
144+
assert isinstance(url, basestring)
145+
assert isinstance(json_dict, dict)
146+
abs_url = self.urljoin(url)
147+
# Process kwargs
122148
timeout = kwargs.pop('timeout', self.timeout)
123-
expected_response_code = kwargs.pop('expected_response_code',
124-
POST_EXPECTED_RESPONSE_CODE)
125-
if kwargs:
126-
raise TypeError(' Unexpected **kwargs: %r' % kwargs)
149+
erc = kwargs.pop('erc', ERC['POST'])
150+
_raise_if_extra_kwargs(kwargs)
127151
# API request
128-
response = self._req_session.post(self.urljoin(url),
152+
response = self._req_session.post(abs_url,
129153
json=json_dict,
130154
timeout=timeout)
131-
_check_response(response, expected_response_code)
155+
# Process response
156+
_check_response_code(response, erc)
132157
return _extract_and_parse_json(response)
133158

134159
def put(self, url, json_dict, **kwargs):
160+
# Process args
161+
assert isinstance(url, basestring)
162+
assert isinstance(json_dict, dict)
163+
abs_url = self.urljoin(url)
164+
# Process kwargs
135165
timeout = kwargs.pop('timeout', self.timeout)
136-
expected_response_code = kwargs.pop('expected_response_code',
137-
PUT_EXPECTED_RESPONSE_CODE)
138-
if kwargs:
139-
raise TypeError(' Unexpected **kwargs: %r' % kwargs)
166+
erc = kwargs.pop('erc', ERC['PUT'])
167+
_raise_if_extra_kwargs(kwargs)
140168
# API request
141-
response = self._req_session.put(self.urljoin(url),
169+
response = self._req_session.put(abs_url,
142170
json=json_dict,
143171
timeout=timeout)
144-
_check_response(response, expected_response_code)
172+
# Process response
173+
_check_response_code(response, erc)
145174
return _extract_and_parse_json(response)
146175

147176
def delete(self, url, **kwargs):
177+
# Process args
178+
assert isinstance(url, basestring)
179+
abs_url = self.urljoin(url)
180+
# Process kwargs
148181
timeout = kwargs.pop('timeout', self.timeout)
149-
expected_response_code = kwargs.pop('expected_response_code',
150-
DELETE_EXPECTED_RESPONSE_CODE)
151-
if kwargs:
152-
raise TypeError(' Unexpected **kwargs: %r' % kwargs)
182+
erc = kwargs.pop('erc', ERC['DELETE'])
183+
_raise_if_extra_kwargs(kwargs)
153184
# API request
154-
response = self._req_session.delete(self.urljoin(url), timeout=timeout)
155-
_check_response(response, expected_response_code)
185+
response = self._req_session.delete(abs_url, timeout=timeout)
186+
# Process response
187+
_check_response_code(response, erc)

0 commit comments

Comments
 (0)