Skip to content

Commit 2dc7c04

Browse files
committed
Merge pull request #230 from JensTimmerman/cleanup
added test + fixes
2 parents 3d0f9a1 + 627f01c commit 2dc7c04

File tree

3 files changed

+42
-37
lines changed

3 files changed

+42
-37
lines changed

lib/vsc/utils/rest.py

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ class Client(object):
7070

7171
USER_AGENT = 'vsc-rest-client'
7272

73-
def __init__(self, url, username=None, password=None, token=None, token_type='Token', user_agent=None, append_slash=False):
73+
def __init__(self, url, username=None, password=None, token=None, token_type='Token', user_agent=None,
74+
append_slash=False):
7475
"""
7576
Create a Client object,
7677
this client can consume a REST api hosted at host/endpoint
@@ -104,78 +105,73 @@ def __init__(self, url, username=None, password=None, token=None, token_type='To
104105
elif token is not None:
105106
self.auth_header = '%s %s' % (token_type, token)
106107

108+
def _append_slash_to(self, url):
109+
"""Append slash to specified URL, if desired and needed."""
110+
if self.append_slash and not url.endswith('/'):
111+
url += '/'
112+
return url
113+
107114
def get(self, url, headers=None, **params):
108115
"""
109116
Do a http get request on the given url with given headers and parameters
110117
Parameters is a dictionary that will will be urlencoded
111118
"""
112-
if self.append_slash:
113-
url += '/'
114-
url += self.urlencode(params)
119+
url = self._append_slash_to(url) + self.urlencode(params)
115120
return self.request(self.GET, url, None, headers)
116121

117122
def head(self, url, headers=None, **params):
118123
"""
119124
Do a http head request on the given url with given headers and parameters
120125
Parameters is a dictionary that will will be urlencoded
121126
"""
122-
if self.append_slash:
123-
url += '/'
124-
url += self.urlencode(params)
127+
url = self._append_slash_to(url) + self.urlencode(params)
125128
return self.request(self.HEAD, url, None, headers)
126129

127-
def delete(self, url, headers=None, **params):
130+
def delete(self, url, headers=None, body=None, **params):
128131
"""
129-
Do a http delete request on the given url with given headers and parameters
132+
Do a http delete request on the given url with given headers, body and parameters
130133
Parameters is a dictionary that will will be urlencoded
131134
"""
132-
if self.append_slash:
133-
url += '/'
134-
url += self.urlencode(params)
135-
return self.request(self.DELETE, url, None, headers)
135+
url = self._append_slash_to(url) + self.urlencode(params)
136+
return self.request(self.DELETE, url, json.dumps(body), headers, content_type='application/json')
136137

137138
def post(self, url, body=None, headers=None, **params):
138139
"""
139140
Do a http post request on the given url with given body, headers and parameters
140141
Parameters is a dictionary that will will be urlencoded
141142
"""
142-
if self.append_slash:
143-
url += '/'
144-
url += self.urlencode(params)
145-
headers['Content-Type'] = 'application/json'
146-
return self.request(self.POST, url, json.dumps(body), headers)
143+
url = self._append_slash_to(url) + self.urlencode(params)
144+
return self.request(self.POST, url, json.dumps(body), headers, content_type='application/json')
147145

148146
def put(self, url, body=None, headers=None, **params):
149147
"""
150148
Do a http put request on the given url with given body, headers and parameters
151149
Parameters is a dictionary that will will be urlencoded
152150
"""
153-
if self.append_slash:
154-
url += '/'
155-
url += self.urlencode(params)
156-
headers['Content-Type'] = 'application/json'
157-
return self.request(self.PUT, url, json.dumps(body), headers)
151+
url = self._append_slash_to(url) + self.urlencode(params)
152+
return self.request(self.PUT, url, json.dumps(body), headers, content_type='application/json')
158153

159154
def patch(self, url, body=None, headers=None, **params):
160155
"""
161156
Do a http patch request on the given url with given body, headers and parameters
162157
Parameters is a dictionary that will will be urlencoded
163158
"""
164-
if self.append_slash:
165-
url += '/'
166-
url += self.urlencode(params)
167-
headers['Content-Type'] = 'application/json'
168-
return self.request(self.PATCH, url, json.dumps(body), headers)
159+
url = self._append_slash_to(url) + self.urlencode(params)
160+
return self.request(self.PATCH, url, json.dumps(body), headers, content_type='application/json')
169161

170-
def request(self, method, url, body, headers):
162+
def request(self, method, url, body, headers, content_type=None):
171163
"""Low-level networking. All HTTP-method methods call this"""
172164
if headers is None:
173165
headers = {}
166+
167+
if content_type is not None:
168+
headers['Content-Type'] = content_type
169+
174170
if self.auth_header is not None:
175171
headers['Authorization'] = self.auth_header
176172
headers['User-Agent'] = self.user_agent
177173
fancylogger.getLogger().debug('cli request: %s, %s, %s, %s', method, url, body, headers)
178-
#TODO: in recent python: Context manager
174+
# TODO: in recent python: Context manager
179175
conn = self.get_connection(method, url, body, headers)
180176
status = conn.code
181177
body = conn.read()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
VSC_INSTALL_REQ_VERSION = '0.10.1'
4040

4141
PACKAGE = {
42-
'version': '2.5.0',
42+
'version': '2.5.1',
4343
'author': [sdw, jt, ag, kh],
4444
'maintainer': [sdw, jt, ag, kh],
4545
# as long as 1.0.0 is not out, vsc-base should still provide vsc.fancylogger

test/rest.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
@author: Jens Timmerman (Ghent University)
3030
"""
3131
import os
32+
from urllib2 import HTTPError
3233

3334
from vsc.install.testing import TestCase
3435

@@ -68,9 +69,17 @@ def test_client(self):
6869
self.assertEqual(status, 200)
6970
self.assertEqual(body['merge_commit_sha'], u'fba3e13815f3d2a9dfbd2f89f1cf678dd58bb1f1')
7071

71-
def suite():
72-
""" returns all the testcases in this module """
73-
return TestLoader().loadTestsFromTestCase(RestClientTest)
74-
75-
if __name__ == '__main__':
76-
main()
72+
def test_request_methods(self):
73+
"""Test all request methods"""
74+
status, body = self.client.head()
75+
self.assertEqual(status, 200)
76+
try:
77+
status, body = self.client.user.emails.post(body='[email protected]')
78+
self.assertTrue(False, 'posting to unauthorized endpoint did not trhow a http error')
79+
except HTTPError:
80+
pass
81+
try:
82+
status, body = self.client.user.emails.delete(body='[email protected]')
83+
self.assertTrue(False, 'deleting to unauthorized endpoint did not trhow a http error')
84+
except HTTPError:
85+
pass

0 commit comments

Comments
 (0)